40人がいいねしました

更新日

img関連で覚えたい、ワンランク上のコーダーになるための8つの知識

web兄さん

imgはコーディングする上で頻出するタグです。それ故に覚えておきたいテクニックが多いタグでもあります。

今回は実務で活かせるimg関連のテクニックや知識を8つまとめてみました。

書いてみると結構な大作になってしまいましたが、しっかり読むことで得られるものは多いと思います👍

  1. レスポンシブ対応用の画像の切り替えは<picture>を使用
  2. レイアウトシフト(CLS)を防ぐ
  3. デバイスピクセル比が異なる場合の画像を用意する
  4. alt属性を正しく書く
  5. 独立した画像コンテンツはfigureでマークアップ
  6. アイコンはsvgタグを利用したほうが便利
  7. 画像の非同期・遅延読み込み
  8. デザインカンプから適切な拡張子で画像を書き出す

レスポンシブ対応用の画像の切り替えはpictureを使用

以下のようにPCとスマホで別々の画像を出力することをアートディレクションといいます。

PCとスマホで画像を切り替えたい場合
PCとスマホで画像を切り替えたい場合

アートディレクションを行いたい場合、従来は以下のように対応していました。

<!-- PCで表示したい画像 -->
<img class="pc-visible"
     src="photo-pc.jpg"
     alt="PC用の画像">

<!-- スマホで表示したい画像 -->
<img class="sp-visible"
     src="photo-sp.jpg"
     alt="スマホ用の画像">
.pc-visible{
  display: none;     /* SP時は隠す */
}

@media (min-width:768px) {
  .pc-visible{
    display: block;  /* PC時は表示 */
  }
  .sp-visible{
    display: none;   /* PC時は隠す */
  }
}
  1. PC用とスマホ用のimgをそれぞれ記述
  2. PCとスマホでそれぞれ表示・非表示になるclassを作成して割り当てる

しかし、あくまでdisplay: noneで非表示にしているだけであるため、PCの時には不要なスマホの画像も読み込まれてしまうという問題がありました。

pictureタグを使用する

pictureは画像のレスポンシブ対応に関する問題を解決してくれます。

<picture>
  <source srcset="PC用の画像パス" media="(min-width: 768px)" />
  <img src="スマホ用の画像パス" alt="サンプル画像"/>
</picture>

ポイントは以下の通りです。

  • 3つのタグは必須<picture><source><img>の順番で書く
  • sourceのsrcset属性には画像のパスを、media属性にはメディアクエリを書く
  • sourceを複数書くことで、画像の出力を細かく分けることも可能

以下のようにブレイクポイントに応じて画像を切り替えることができます。

pictureタグを使用した画像の切り替え

レイアウトシフト(CLS)を防ぐ

レイアウトシフト(CLS)とは画像が読み込まれるタイミングが遅れることで、読み込み前と、読み込んだ後でWebページのレイアウトにズレが生じることです。

レイアウトシフトによってユーザーが不満を抱く例
レイアウトシフトによってユーザーが不満を抱く例

特にスマホでWebサイトを閲覧しているときに「スクロールしようとして誤って広告をタップしてしまう」なんてことありませんか?

これって結構なストレスですよね。

画像以外にもレイアウトシフトは起こる

レイアウトシフトは画像だけではなく、動的に挿入されたコンテンツやWebフォントの読み込みによっても起こります。今回はimgがメインの記事なので割愛しますが、詳しく学習したい方はこちらをお読みください。

width属性とheight属性を書いておく

もっともシンプルな方法はimgheightwidthを追加する方法です。

表示する画像サイズと同じサイズをあらかじめimgに追記しておきます。

実際の表示と同じ、つまりデザインカンプと同じ画像の幅と高さを記述する。
width属性とheight属性を指定する

レスポンシブで画像を切り替える場合

以下のようにPCとSPで表示を切り替えるアートディレクションを行う場合はaspect-ratioを用いた方法が推奨されています。

PCとスマホで画像を切り替えたい場合
PCとスマホで画像を切り替えたい場合
<picture>
  <source srcset="PC用の画像パス" media="(min-width: 768px)" />
  <img src="スマホ用の画像パス" alt="サンプル画像"/>
</picture>
img{
  aspect-ratio: 600 / 500;   /* スマホ時の比率 */
}

@media (min-width: 768px){
  aspect-ratio: 335 / 250;   /* PC時の比率  */  
}

デバイスピクセル比が異なる場合の画像を用意する

デバイスピクセル比とはCSS上での1pxと実際のデバイスの解像度の比率のことです。

デバイスピクセル比の考え方
デバイスピクセル比の考え方

例えば、iPhone8の場合は以下の通り「デバイスピクセル比が2」となります。

  • 端末のサイズ(CSSピクセル)は375px(横) × 667px(縦)
  • しかし、実際の画面解像度は750px(横) × 1334(縦)
  • 750px / 375px = 2 = デバイスピクセル比は2

つまり、iPhone8でWebサイトを閲覧している時は、実際には1pxあたりに4つのドットがあり、より鮮明に画像を認識できるようになっています。

テレビの画質の高さも同じ様な原理ですね。

高画質なテレビほど、1インチあたりに処理できる色の情報が多いので同じ画面サイズのテレビでも低画質と高画質に分かれます。


デバイスピクセル比はスマホだけでなく、PCにも存在しており、

  • WindowsのPC:デバイスピクセル比は「1」
  • MacのPC:デバイスピクセル比は「2」

となっています。

デバイスピクセル比が高いほど、サイズの小さい画像は画質が下がって見える

「高解像度だから、MacのほうがWindowsよりも画質良く見えるんでしょ?」と思ってしまいますよね。しかし以下を見てください。

デバイスピクセル比の違いで画像がボケる例
Macのほうが画質が下がって見える

右側のMacで表示している画像のほうがボヤけて見えます。

これは、Macのほうが解像度が高いため、画像のきめ細かい部分まで見えすぎてしまうためです。

身近なもので例をあげると、画質の低いカメラで撮影したほうが肌が綺麗に見えて、画質の高いカメラで撮影したほうがより鮮明に捉えることができるので肌の荒れが目立ちますよね。

このようにデバイスピクセル比の高い端末で閲覧することを想定してサイズの違う画像を用意しておく必要があります。

デバイスピクセル比ごとの画像を用意する

Figmaを例にします。

以下のようにエクスポートの「+」を押すとその分デバイスピクセル比に対応する用のx倍のサイズの画像が出力できるようになります。

Figmaでサイズ違いの画像をエクスポートする方法

エクスポートするとこの通り、名前とサイズとの異なる画像がダウンロードされます。

Figmaのサイズ違い画像のエクスポート (1)
名前とサイズの異なる画像がダウンロードされる

サイズを見ると@2xは2倍サイズ、@3xは3倍サイズとなっていますよね。

この@xという名前はデバイスピクセル比対応の画像のファイル名によく使用される名前です。

srcset属性で画像を出し分ける

用意した画像を以下のようにsrcset属性を使って読み込みます。

<img
  srcset="dog.jpg,
          dog@2x.jpg 2x,
          dog@3x.jpg 3x,
          dog@4x.jpg 4x"
  src="dog.jpg"
  width="400" height="400" alt="犬">

srcset="ファイル名 デバイスピクセル比"を記述することで、ブラウザが自動でデバイスのデバイスピクセル比を計算して適切な画像を読み込んでくれるようになります。

alt属性を正しく書く

alt属性は画像が表示されない時の代替テキストであると同時に、スクリーンリーダーやGoogleのロボットがWebページの情報を読み取るための参考にもされます。

altを正しく書くためには「不要・必要を判断できるようになる → 必要な場合の正しい書き方を覚える」という流れが大切です。

altが不要なケース

❌画像が装飾用であり、それ自体が意味を持たない場合にはaltは書きません。

例えば、アイコンはaltが不要な場合がほとんどでしょう。

以下のボタンのケースではクリックでどんなアクションが起こるのかテキスト情報が書いてあります。

よって視覚情報を補足する役割のアイコンにaltは不要です。

<!-- ❌装飾用のアイコンはalt不要 -->
<button>
  <span>カートへ入れる</span>
  <img src="icon-cart.svg" alt="カートのアイコン">
</button>

他にもテキストだけでは味気ないので、デザインのクオリティを上げるために挿入されている写真やイラストも同様にaltは不要です。

<!-- ❌装飾用のはalt不要 -->
<h2>事業内容</h2>
<div>
  <img src="babysitter.jpg" alt="ベビーシッターの仕事風景のイメージ">
  <h3>ベビーシッター事業</h3>
  <p>〇〇〇〇〇〇〇〇...</p>
</div>

altが必要なケース

⭕️画像がなくなった場合に情報が不十分になる場合は書く

例えば、見出し自体が画像であるケース。

この「50%OFF SALE」という画像がない場合は「情報が不十分」になりますよね。

そのためaltは必須と言えます。

<!-- ⭕️画像がテキスト情報を持つ場合 -->
<img src="sale.png" alt="50%割引のセール">
<p>超お得な割引セール!期間限定で開催👏</p>

バナーも同様の考え方です。

画像だけで表示されるバナーはaltが記載されていない場合、読み取れる情報が一切なくなってしまうので必須です。

<!-- ⭕️テキスト情報を多く持つ画像 -->
<img src="banner.png" alt="レンタル・販売が30%OFFになる、公式サイト限定クーポンのバナー">

altが不要・必要どちらでも良いケース

以下のようなケースはテキストの情報と関連しているため、装飾用の画像ではありません。

しかし、画像自体が無くなった場合でも情報としては成り立ちます。

この場合はどちらの解釈もあると言えますが書いてあったほうが無難と言えそうです。

<!-- ⭕️あってもなくても困らない -->
<div>
  <p><img src="yamada.jpg"></p>
  <div>
    <h2>代表挨拶</h2>
    <p>創業して20年、変わらぬ味を...</p>
  </div>
</div>

altの理想的な書き方

altはキャプションのような抽象的なタイトルではなく、画像を口頭で人に説明できるような文章で書くことが理想的です。

例えば先ほどのバナーの例で悪いパターンと良いパターンを見てみましょう。

<!-- ❌Bad(理由:それが"何であるか"を説明しているから) -->
<img src="banner.png" alt="セールのバナー">

<!-- ⭕️Good(理由:画像のテキスト情報をしっかりと"説明している"から)-->
<img src="banner.png" alt="レンタル・販売が30%OFFになる、公式サイト限定クーポンのバナー">

前者のaltの場合、セールのバナーであることは分かっても、詳細な情報はわかりません。

バナー画像内のテキストとaltのテキスト一致していたほうがいい?
完全に一致する必要はありません。デザインの都合上、文章になっていないケースがほとんどであるため、内容が伝わるように作文してaltに書いてもOKです。
しかし、画像と無関係のテキストをSEO目的で入れることはスパム扱いになるので注意しましょう⚠️

独立した画像コンテンツはfigureでマークアップ

画像がコンテンツとして独立(自己完結)している場合はimgfigurefigcaption(注釈)使ってマークアップをすることができます。

例えば以下のような図は、別の箇所に移動させても成り立つ画像コンテンツですよね。

レイアウトシフトによってユーザーが不満を抱く例
レイアウトシフトの例
<figure>
  <img src="camera.jpg" alt="スクロールしようとしたら遅れて表示された広告をクリックしてしまった">
  <figcaption>レイアウトシフトの例</figcaption>
</figure>

figcaptionは必須?

figcaptionは必須ではないですが、figureの定義が独立しているコンテンツということを考慮すると、必要になってくるケースが多いです。写真だけで独立させようとすると情報が足りなくなってしまうからです。


Web制作での活用例

ただ、実際のWeb制作で図をマークアップすることってほとんどありませんよね。

個人的な解釈では以下のような実績一覧や商品写真に関してはfigure+figcaptionでマークアップしても良いと考えています。

イメージとしては以下の通りです。

<article>
  <figure>
   <img src="My Portfolio Website" alt="My Portfolio Websiteのメインビジュアル">
   <figcaption>
     <time datetime="2022-09-22">2022.09.22</time>
     <h2><a href="#">就活用のポートフォリオサイトを作成しました。就活用のポート...</a></h2>
   </figcaption>
  </figure>
</article>

figureが不要な例

逆に、以下のようなデザインとして配置されている画像は独立していないコンテンツなのでfigureで定義する必要はありません。

文脈としておかしくなければp、レイアウトの便宜上ということであればdivの入れ子にすればOKです。

アイコンはsvgタグを利用したほうが便利

通常時とhover時で色違いのアイコンを用意する必要がある

テキスト+アイコンのボタンを実装する時は、

  • 擬似要素で配置
  • imgで拡張子を.svgにして読み込む

上記の手法が一般的ですよね。

しかしこの方法の場合、hoverで色を反転させたい時用に色の異なるアイコンを用意しておく必要があります。

SVGタグでマークアップしてfill: currentColorを設定する

以下の用にSVGタグを使ったマークアップをすることで、アイコンの色をCSSでコントロールすることができます。

<button class="button-cart">
    カートに入れる
    <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M4.80001 1.59998C4.37567 1.59998 3.9687 1.76855 3.66864 2.0686C3.36858 2.36866 3.20001 2.77563 3.20001 3.19998C3.20001 3.62432 3.36858 4.03129 3.66864 4.33135C3.9687 4.6314 4.37567 4.79998 4.80001 4.79998H6.75201L7.24001 6.75518C7.24486 6.77769 7.25019 6.80009 7.25601 6.82238L9.42881 15.5104L8.00001 16.9376C5.98401 18.9536 7.41121 22.4 10.2624 22.4H24C24.4244 22.4 24.8313 22.2314 25.1314 21.9313C25.4314 21.6313 25.6 21.2243 25.6 20.8C25.6 20.3756 25.4314 19.9687 25.1314 19.6686C24.8313 19.3685 24.4244 19.2 24 19.2H10.2624L11.8624 17.6H22.4C22.6971 17.5998 22.9882 17.517 23.2409 17.3607C23.4935 17.2044 23.6976 16.9809 23.8304 16.7152L28.6304 7.11518C28.7523 6.8713 28.8098 6.60034 28.7975 6.32799C28.7853 6.05564 28.7036 5.79094 28.5603 5.55901C28.417 5.32708 28.2168 5.13561 27.9788 5.00277C27.7407 4.86993 27.4726 4.80012 27.2 4.79998H10.048L9.55201 2.81118C9.46534 2.46518 9.26554 2.15807 8.98434 1.93862C8.70315 1.71918 8.3567 1.59998 8.00001 1.59998H4.80001ZM25.6 26.4C25.6 27.0365 25.3472 27.6469 24.8971 28.097C24.447 28.5471 23.8365 28.8 23.2 28.8C22.5635 28.8 21.953 28.5471 21.503 28.097C21.0529 27.6469 20.8 27.0365 20.8 26.4C20.8 25.7635 21.0529 25.153 21.503 24.7029C21.953 24.2528 22.5635 24 23.2 24C23.8365 24 24.447 24.2528 24.8971 24.7029C25.3472 25.153 25.6 25.7635 25.6 26.4ZM10.4 28.8C11.0365 28.8 11.647 28.5471 12.0971 28.097C12.5472 27.6469 12.8 27.0365 12.8 26.4C12.8 25.7635 12.5472 25.153 12.0971 24.7029C11.647 24.2528 11.0365 24 10.4 24C9.76349 24 9.15304 24.2528 8.70296 24.7029C8.25287 25.153 8.00001 25.7635 8.00001 26.4C8.00001 27.0365 8.25287 27.6469 8.70296 28.097C9.15304 28.5471 9.76349 28.8 10.4 28.8Z" fill="white"/>
    </svg>
</button>

CSSではsvg > pathをセレクタにします。

pathの色はfillで変更が可能です。例えばredとすれば赤色になりますが、今回は親要素の色を継承するcurrentColorを設定しています。

currentColorを設定することで、親である.button-cartに設定されているcolorを受け継ぐため、通常時は#333になり、ホバー状態では#fffにできるというテクニックです。

/* ボタンの配色 */
.button-cart{
  color: #333;
  background-color: #efefef;
  transition: color 0.6s,background-color 0.6s;
}

/* svgのpathの色を設定 */
.button-cart path {
  fill: currentColor;
}

/* hover状態 */
.button-cart:hover{
  background-color: #333;
  color: #fff;
}

書き出したsvg画像をSVGタグに変換するには?

.svgで書き出した画像を、VS Codeにドラッグ&ドロップするか、ファイルとして開くことでSVGタグが自動で生成されます。

SVGタグに変換する方法

画像の非同期・遅延読み込み

imgsrcalt以外の属性も設定することができますが、その中でも取り分け覚えておきたいのがdecoding属性loading属性です。

decoding属性|画像を非同期で読み込む

画像は通常他のコンテンツの表示を待ってから読み込まれるため時間がかかります。

しかしdecoding="async"を記述することで非同期(他のコンテンツと並行して読み込まれる)で画像を読み込ませることができます。

<img width="300" height="100" src="photo.jpg" decoding="async">

loading属性|画像を遅延して読み込む

ページが読み込まれるとそのページで必要な画像が全て読み込まれます。

そのため、以下の例のように表示されていない画像の読み込みがページ全体の表示速度に影響を及ぼしてしまいます。

画像がブラウザに表示されるタイミングで読み込むように遅延したい場合にloading="lazy"を追記します。

<img width="300" height="100" src="photo.jpg" loading="lazy">

decodingとloadingは一緒に書いてもOK

<img src="photo.jpg" decoding="async" loading="lazy" width="300" height="100">

上記のように併せて記述することも可能です。ちなみにどちらも書いてある場合、Chromeではloading="lazy"が優先されるようです。

デザインカンプから適切な拡張子で画像を書き出す

Webサイトで表示されている画像には以下のように様々な種類がありますが、それぞれ最適な拡張子が存在しています。

  • 写真
  • イラスト
  • アイコン

デザインカンプではどの拡張子で出力するかの指示はないため、コーダーの判断に委ねられます。

そのため、意外となんとなくで書き出しを行なっている方も多いのではないでしょうか?

極論を言えば「希望通りに画像を表示できていればOK」なのですが、最適な拡張子を選択することで画像のパフォーマンスを最大限引き出し、主にWebサイトの読み込み速度の改善につなげることができます。


こちらに関しては別記事で恐縮ですが、フローチャート付きで詳しくまとめてあるのでぜひ参考にしてください。

画像の拡張子選定フローチャート
画像の拡張子選定フローチャート
よくある画像のタイプから逆引き
画像のパーツごとの拡張子一覧

スクール越えの圧倒的なコスパ1ヶ月でWeb制作を身に着ける

プロのメンターサポート付き実務レベルのコーディングカリキュラム

詳細を今すぐチェック!

ギャクサンで作成するポートフォリオサイトのイメージ

記事では見れない豆知識

圧倒的なコスパを体感1ヶ月でWeb制作を身に着ける

プロのメンターサポート付き実務レベルのコーディングカリキュラム

詳細を今すぐチェック!

ギャクサンで作成するポートフォリオサイトのイメージ