srcsetとsizes属性でサイズ(解像度)ごとに画像を出し分ける方法

レスポンシブデザインを採用しているWebサイトでは、デバイスごとに適正なサイズ(解像度)の画像を読み込ませる、という課題があります。

特に、高解像度のスマートフォンが登場したことで、画像がぼやけてキレイに表示されないと言う新たな問題も出てくるようになりました。

表示サイズの調整に加え、高解像度ディスプレイへの対応という2つの点から画像を最適化するのが常識になってきています。

以前なら、こういった問題に対応するには JavaScript を用いた面倒な実装が必要でしたが、現在はHTMLだけで解決することができます。

それが srcset や sizes 属性の利用です。
この記事では srcset とsizes 属性の書き方・使い方について詳しく解説していきます。

少し慣れが必要かもしれませんが、非常に便利な機能です。

srcset と sizes 属性とは

srcset属性とは、HTML5.1から追加された属性で、サイズ違いの画像を条件によって切り替える機能です。imgタグ または pictureタグ内のsourceタグ で使えます。

表示したい画像の候補を複数記述して、閲覧環境に応じて最も適切な画像を自動で読み込んでくれます。

srcsetでは、読み込まれる画像は適切な1枚のみであって、表示しないその他の候補画像を無駄にロードしません。

Lazy Load (画像の遅延読み込み) との相性が悪い場合があるようなので要検証です。

sizes属性は、srcsetを指定した画像の表示サイズ(描画サイズ)を、条件によって切り替えり指定です。

srcsetは画像ファイル自体の切り替えを行い、sizesは表示サイズを変化させるというそれぞれの役割になります。

対応ブラウザ

srcset と sizes 属性のブラウザのサポート状況

Can I use… Srcset and sizes attributes

srcset と sizes 属性は多くのブラウザで対応していますが、IE (Internet Explorer) は未対応です。

未対応のブラウザでも通常の img 要素として読み込まれるため、画像が表示されないわけではないので、使用をためらわなくても大丈夫です。

未対応ブラウザでは sizes 属性は無視されます。

picturefillというJavaScriptを利用すれば、 未対応ブラウザにも同様の機能を持たせることができます。

srcset 属性の書き方

<img srcset="画像URL1 記述子1, 画像URL2 記述子2, 画像URL 記述子3, …" src="デフォルト画像URL">

画像URLと記述子(デスクリプタ)をセットとして、カンマで区切って複数の画像候補を書いていきます。

画像URLと記述子の間は半角スペースを空けます。
記述子には、画像を読み込む条件を指定します。

記述子に使える単位は、ビューポート (ブラウザ表示領域) の横幅 w か、デバイスピクセル比を表す x です。

srcset内の記述子は統一します。

当たり前ですが、同じ srcset 内の異なる記述子に、全く同じ値を書くことはできません。
例えば、1つ目の記述子に 300w として、2つ目の記述子も 300w と書くのは、競合するためNGです。

記述子がない場合は 1x と見なして処理されます。

srcset を書く時は src 属性の記述も必須で、未対応のブラウザが読み込むデフォルトの画像を指定します。

それでは、記述子ごとの記述方法を確認していきましょう。

※ここからの解説では省略していますが、alt属性の記述も必須です。

デバイスピクセル比での指定方法 (x)

デバイスピクセル比で切り替える時は、ピクセル密度の記述子 x を使います。

レスポンシブイメージの検証画像

<img srcset="img-720w.png 2x, img-540w.png 1.5x, img-360w.png 1x" src="default-image.png" width="360" height="200">

上記サンプル画像では、Retinaディスプレイなどのデバイスピクセル比が 2 の端末ならば 720、比率 1.5 なら 540、 比率 1 なら 360 という横幅の数値が書かれた画像が表示されているはずです。

表示サイズが固定されていて、ピクセル密度に合わせて切り替える時は x の記述子は使いやすいでしょう。

ビューポート幅での指定方法 (w)

ビューポート幅(表示領域の横幅)に応じて画像を切り替える時は、幅記述子 w の単位を使います。

ブレイクポイントとなるビューポート幅のピクセル数値を記述します。

レスポンシブイメージの検証画像

<img srcset="img-1440.png 1440w, img-720.png 720w, img-360.png 360w" src="default-image.png">

幅記述子 w で指定する場合でも、デバイスピクセル比は自動的に考慮されます。

デバイスピクセル比が 1 の場合、上のサンプル画像はビューポート幅が360pxまでは img-360.png が、720pxまでは img-720.png が、それ以上のサイズで img-1440.png が表示されます。

デバイスピクセル比が 2 であったなら、360px幅でも img-720.png が、720px幅以上で img-1440.png が読み込まれます。

このように、表示サイズとデバイスの解像度の両方から算出して、適切な画像が読み込まれます。

sizes 属性の書き方

<img sizes="画像の表示幅" srcset="…" src="…">

sizes属性はsrcset属性がある場合のみ記述できます。
また、sizesを利用する時はsrcsetの記述子は必ず w の単位で書きます。

sizes属性の値には、画像の横幅の表示サイズを指定します。

長さの指定には em, rem, px, cm, pt などCSS Values and Units Module Level 3で定義されている『長さの単位』が使用できます。

calc() 関数を利用した長さの指定もできます。

sizes属性では、CSSでおなじみの % による指定はできません。

割合で指定したい時には、ビューポート(ブラウザ表示領域)に対する割合で記述します。
単位とその意味は以下の表のとおりです。

ビューポート (viewport) に対する割合を示す長さの単位
単位 意味
vw ビューポートの横幅の長さを100 (%) とした割合
vh ビューポートの縦の長さを100 (%) とした割合
vmin ビューポートの縦横いずれかの小さい数値に対する割合
vmax ビューポートの縦横いずれかの大きい数値に対する割合

例えば、ビューポート幅の半分のサイズで画像を表示するなら sizes="50vw" と指定します。

スマートフォンの場合、vwvh は縦向き (ポートレートモード) と横向き (ランドスケープモード) によって算出される数値は変化します。

vmin での指定は、ビューポートが 360x600px なら、短い方の 360px が算出する基準値となります。

したがって、10vmin ならば 36px の横幅で表示されます。
100vmin なら幅いっぱい (360px) の表示ですね。

vmax は 360x600px のビューポートなら 600px に対する割合と言った具合です。

レスポンシブイメージの検証画像

<img sizes="50vw" srcset="img-1440.png 1440w, img-720.png 720w, img-360.png 360w" src="default-image.png">

上記コードサンプルでは、ビューポート幅の半分の横幅で表示され、その画像幅とデバイスピクセル比から算出して適切なサイズの画像が呼び出されます。

例えば、ビューポート幅が 720px なら画像は 360px の大きさで表示されますが、デバイスピクセル比が 2 の端末なら img-720.png が読み込まれます。

メディアクエリによるサイズ切り替え

sizes属性ではメディアクエリが利用できるので、デバイスのビューポート幅に応じて画像の表示サイズを切り替えることができます。

<img sizes="(メディアクエリ1) 長さ1, (メディアクエリ2) 長さ2, …" srcset="…" src="…">

メディアクエリはカッコで囲み、半角スペースを空けて、表示したいサイズを指定します。
カンマで区切って複数指定できます。

レスポンシブイメージの検証画像

<img sizes="(max-width: 360px) 100vw, (max-width: 800px) 75vw, 50vw" srcset="img-1440.png 1440w, img-720.png 720w, img-360.png 360w" src="default-image.png">

このサンプルでは、ビューポート幅が 360px までの場合は画像は幅いっぱいまで広がります。

ビューポート幅 361 〜 800px までは、ビューポート幅の75%の横幅サイズで表示されます。
例えば、ビューポート幅が 600px ならば、画像は横 450px で表示されます。

最後の 50vw はメディアクエリを指定していないため、各メディアクエリに当てはまらない時に適用されます。

つまり、ビューポート幅が801px以上の時に、その50%の横幅サイズで画像が表示されます。

srcsetはレスポンシブイメージの実装に必須

srcset とsizes 属性について解説してきましたが、いかがでしたか?

とても便利な機能、と言うより、レスポンシブイメージの実装には、もはや必須と言える機能です。

ブラウザがネイティブでサポートしているので、JavaScriptを使って画像を切り替えるよりもページの処理パフォーマンスも上がります。

レスポンシブイメージの実装には、picture要素と言うさらに便利なタグがありますが、pictureを利用する時にも srcset や sizes の記述を利用します。

srcset とsizes 属性は、これからのWebサイトで当たり前になっていくので、ぜひともマスターしておきましょう。

コメント

コメントを残す

*

ページ上部へ戻る