レンちゃんとペンタ

【画面サイズ・解像度ごとに最適な画像を出し分ける】srcset属性とsizes属性

【画面サイズ・解像度ごとに最適な画像を出し分ける】srcset属性とsizes属性

同じWebページでも、パソコンで表示された時には解像度の高い画像を、スマホでは小さめの画像を提供したい。
といったように、ユーザーの閲覧環境によって最適なサイズの画像を提供できるのがsrcset属性です。
選定した画像の表示サイズは、sizes属性で設定することができます。

    Webデザインとブログで豊かに引きこもる。

    レンちゃんとペンタ

    Webデザインは器。ブログは中身。
    「レンちゃんとペンタ」では、2つのスキルを掛け合わせて、
    おウチで豊かに楽しく暮らす方法をご紹介しています。

    srcset属性の使い方

    こんな時に便利です

    srcset属性を使うと、

    ・スマホ:小さい画像
    ・タブレット:中くらいの画像
    ・パソコン:大きい画像

    のように、閲覧環境に応じて表示させる画像を切り替えることができます。

    srcset属性の利用イメージ
    閲覧環境の画面サイズ・解像度にピッタリの画像が表示されます

    画面幅を基準にした設定

    例えばこんなサンプルを考えてみます。

    サンプル
    以下のような条件で画像を出し分けたい場合、

    ・画面幅が〜400pxの場合:small.png(画像の幅400px)
    ・画面幅が400px〜800pxの場合:medium.png(画像の幅800px)
    ・画面幅800px〜1200pxの場合:large.png(画像の幅1200px)

    img要素にsrcset属性を加えて、このように表記します。

    <img srcset="small.png 400w, medium.png 800w, large.png 1200w" />
    

    「400w」の「w」は幅記述子です。「400w / 800w / 1200w」がそれぞれ画面の幅を表しています。
    詳細は後述していますが、ここでは「400w = 400px」として話を進めます。

    IEなどsrcset属性に対応していない環境を考慮して、src属性を併用することもできます。

    <!-- 
    src属性を合わせた例。
    srcset属性に対応していない環境では、extra.pngが表示されます。
     -->
    <img srcset="small.png 400w, medium.png 800w, large.png 1200w"
         src="extra.png" />
    

    デバイスピクセル比を基準にした設定

    画面幅の代わりに、デバイスピクセル比を基準とした出し分けを行うことも可能です。
    AppleでいうところのRetinaのように、画素密度が高い環境では高解像度の画像を提供する、といった設定ができます。

    サンプル
    以下のような条件で画像を出し分けたい場合、

    ・デバイスピクセル比1の環境:small.png
    ・デバイスピクセル比2の環境:large.png

    表記はこのようになります。

    <img srcset="small.png 1x, large.png 2x" />

    「1x」がデバイスピクセル比1を表します。「x」は密度記述子です。
    例えばデバイスピクセル比2の環境であれば、画面幅とは関係なくlarge.pngが表示されます。

    ところでsrcset属性では、「どの画像を表示させるか」は選定できているのですが「どのくらいの大きさで表示させるか」までは指定しきれていません。
    srcset属性で選択した画像の表示サイズは、次に紹介するsizes属性で設定することができます。

    sizes属性の使い方

    同じサイズを指定する場合

    サンプル
    以下は、srcset属性で選定した画像を、一律50vwで表示させる場合のサンプルです。

    <img srcset="small.png 400w, medium.png 800w, large.png 1200w"
         sizes="50vw" />
    

    異なるサイズを指定する場合

    サンプル
    画面幅によって表示サイズを変更したい場合は、こんな書き分けもできます。

    <img srcset="small.png 400w, medium.png 800w, large.png 1200w"
         sizes="(max-width: 400px) 100vw, 
                (max-width: 800px) 50vw, 
                (max-width: 1200px) 25vw" />
    

    ちょっと違和感のある数値設定ですが、srcset属性で選んだ画像がそれぞれ以下のサイズで表示されます。

    ・画面幅が〜400pxの場合:画像幅100vwで表示
    ・画面幅が400px〜800pxの場合:画像幅50vwで表示
    ・画面幅が800px〜1200pxの場合:画像幅25vwで表示

    この「srcset属性で選んだ画像」がちょっと厄介なので注意。

    利用時はココに注意

    画像選定の計算方法

    例えば先程のコレに関して、
    「画面幅が400px〜800pxの場合:画像幅50vwで表示」
    選ばれる画像はsmall.png、medium.png、large.pngのうちのどれでしょうか。

    「400px〜800px」だから、medium.pngではないか。
    と思いきや、正解はsmall.pngです。

    このケースの場合、画面幅400px〜800pxのレンジに50vwで表示させるのだから、必要な画像サイズは200px〜400pxなんですよね。
    だからsmall.pngで十分だろう、とブラウザが判断します。

    Retina等での計算方法(密度記述子「w」の考え方)

    もう一つ気をつけたいのがRetina等の高密度な閲覧環境。
    解説用にもう一度最初のコードに戻ります。

    <img srcset="small.png 400w, medium.png 800w, large.png 1200w" />

    先程は「400w = 400px」という前提でお話をしましたが、実はこれはデバイスピクセル比が1の時に成り立ちます。
    デバイスピクセル2の場合は「400w = 200px」換算になるので、注意が必要です。

    ブラウザによって挙動が異なる

    実装したsrcset属性の確認手段として一番カンタンなのは、ブラウザ幅を伸び縮みさせて画像が切り替わったかチェックする方法です。
    ところがこの画像の切り替わりルール、ブラウザによって少しずつ違いがあります。

    Firefox : 画面幅に合ったサイズの画像が都度適用される
    画面幅を変えるたびに適切な画像に切り替わります。期待通りの挙動ですね。

    Chrome : 読み込まれた画像のうち、一番高解像度の画像を採用
    例えば、以下のような操作行った場合、
    1.最初は狭いブラウザ幅にしておく(small.pngが表示される)
    2.ブラウザ幅をちょっと広げる(medium.pngが表示される)
    3.再び狭いブラウザ幅に戻す

    3で再びsmall.pngに戻るのでは、と思いきや、Chromeでは1〜2の工程で読み込まれた画像のうち一番高解像度のモノ、つまりmedium.pngが表示されっぱなしになります。
    キャッシュをクリアしたり、別ウインドウ、別タブでもう一度Webページを開き直してあげると全てリセットされます。

    私はコレがわかっていなかったので、Chromeで何回もチェックして「おかしいなー、おかしいなー」と悩んでいました。

    Safari : 初動の画面幅用の画像を表示
    先述したコードにおいて、例えばブラウザ幅1200wの状態でページを閲覧するとlarge.pngが表示されるわけですが、その後画面幅を狭めてもsmall.pngやmedium.pngにはならず、ずっとlarge.pngのままになります。

    画像を切り替えるメリット

    こうした画像の切り替え実装ですが、そもそも何のために行うのでしょう。

    閲覧環境に最適な画像を提供するため

    Webページに利用する画像は、高解像度であるほどデータサイズも重くなります。
    例えばスマホでの閲覧に、パソコン向けの大きな画像を表示させるのは余計な負荷です。そこで、

    ・パソコンの大きな画面では、解像度の高い画像を提供する
    ・スマホの小さな画面では、手頃な解像度の画像を提供する

    のように、それぞれの環境に適した画像を出し分けよう、というわけです。

    GoogleのWebページ評価対策

    一般的に、Webページ内で利用する画像の解像度が高いほど、掲載点数が多いほど、ページの読み込み時間(ページ全体が表示されるまでのスピード)も長くなります。
    そしてこのローディング時間は、GoogleがWebページ評価の基準としているCore Web Vitalsの指標の一つとして掲げられています。

    ページ評価で最も大切なのはもちろんコンテンツの中身ですが、仮に同レベルのコンテンツが掲載されたページが2つあったら、読み込み速度が速いページの方が高く評価されるかもしれない、言うことです。
    この辺り、画像を最適化することで少しでも優位に立てるのなら、対応しておく価値はありますよね。

    まとめ

    • 画面幅ごとに画像を出し分ける:srcset属性
    • 出し分けた画像の表示サイズを設定する:sizes属性
    • 画像の切り替えルールはブラウザごと違いがあるので注意

    ロジックが複雑なsrcset属性とsizes属性ですが、結論としては、とにかくブラウザが自ら一番最適な画像を選んでくれるんだ、ということです。

    またそもそも論として、srcset属性を使うには同じ絵柄の画像をサイズ違いで複数用意する必要があるので、なかなかの手間なんですよね。
    実は私は、先述したGoogleのCore Web Vitalsを測定できる公式プラグイン「Lighthouse」でWebページの読み込み速度をチェックし、スコアがそれほど悪くないページに関してはsrcset属性は使いません。

    理想的なのは、Webサイト内の全画像に対応する事なのでしょうが、高解像度の画像を掲載しているページや画像を多用しているページなどから施していくというのもアリだと思います。

    1. Home
    2. 【画面サイズ・解像度ごとに最適な画像を出し分ける】srcset属性とsizes属性

    Related Posts