LoginSignup
11

More than 5 years have passed since last update.

imgのsrcset属性について

Posted at

TL;DR

  • 油断すると忘れるのでメモ。
  • MDNで久しぶりに読み直したら、メディア条件とスロット幅で腑に落ちた。
  • 2xとかするとsizes無効ってか、w記述子でもピクセル密度に対応してたのが意外だった。

参考

レスポンシブ画像の作り方 - MDN

See the Pen img srcset by Yasuo Fukuda (@sigwyg) on CodePen.

srcsetとは

ユーザーエージェントが 利用可能な、ソース画像のセットを示すリスト。提示されたリストはあくまでヒントです。実際にどの画像を選択するか、ユーザーエージェントには、かなりの裁量が与えられています。

多少条件が緩くても良しなに解釈してくれる。指定漏れやミスを許容できるファジーさが売り。(Media Queryだと絶対的なので、想定外に弱い)

確認方法

Chrome DevToolsだと、「Network」タブにて対象ファイルを選ぶと、Previewで確認できる。

  • ページ再読み込みで確認できる(合致するリソースのみ読み込む)
  • Chromeでテストするときはキャッシュ画像が優先されるので、[Disable cache]をオンにしておくこと

スクリーンショット 2018-09-21 21.18.30.png (634.9 kB)

プレビュー画像そのものは実寸幅ではないので注意。この表示画像はDevToolsの表示サイズで拡大縮小される。よく見ると下のほうに 200x150 とあるので、そっちが実際のサイズを表している。

w 記述子を指定した場合

<img srcset="elva-fairy-320w.jpg 320w,
             elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px"
     src="elva-fairy-800w.jpg" alt="妖精の衣装を着たエルバ">
  • srcsetで表示画像の候補を指定する
  • w記述子は画像の実サイズ(表示サイズだと解像度の影響を受ける。MacだとCommand+iで分かる)
  • sizesにメディア条件とスロット幅(表示領域)を指定する
  • メディア条件が真となるとき、対応するスロット幅に最も近い画像が読み込まれる
  • sizesの判定は記述順

「画面幅320px以下の場合に、280pxの領域に突っ込む」となる。
ブラウザはsrcsetにて提示された候補から、スロット幅に適用するのに最適な画像を選んで表示する。これには画面解像度も加味される

なお、srcsetを解釈しないブラウザは、単純にsrcで指定されたリソースを読み込む。

x 記述子を指定した場合

<img srcset="elva-fairy-320w.jpg,
             elva-fairy-480w.jpg 1.5x,
             elva-fairy-640w.jpg 2x"
     src="elva-fairy-640w.jpg" alt="妖精の衣装を着たエルバ">
  • sizes は必要ない(混ぜるな危険)
  • ブラウザーは、表示されている画面の解像度を単純に調べ、(srcsetで提示された候補から)最も適切な画像を提供する。
  • 1xは暗黙のため、含める必要はない

注意点

  • 幅記述子(w)と画素密度記述子(x)を、同一の srcset 属性に混在させると無効になる
  • 重複した記述子も無効(2xが2つある場合など)
  • sizesの判定では、最初に一致した条件の後はすべて無視される(記述順に注意)
  • <meta name="viewport" content="width=device-width"> を設定していること

JavaScriptではできないのか?

JavaScriptを読み込んで解釈する前に、画像の先読みが開始している。JavaScriptで判定して出し分けようとすると、複数のリソースを読み込んでしまう。

CSSでやる場合

Media Queryで実装する。
いちお対応するリソースのみ読み込んでいる模様。(以前は全部読んでた気がする)

See the Pen Media Queryで個別に画像が読まれるか? by Yasuo Fukuda (@sigwyg) on CodePen.

こちらはsrcsetと違って厳密なので、良くも悪くも書かれた以上のことはしない。この例でいうと、ピクセル密度が3xなiPhone Xとか、device-width: 375pxなiPhone 8 とか、414pxなiPhone 8 Plusとかは考慮しない。画面幅320px以下なら320pxの画像を適用する。

よくわからないこと

実際にはサイズ違いだけでなく、srcsetsizesでPC/SPで全く違う画像も提供できるため、picture要素を使う意義があまり見出せない。MIMEタイプのサポート状況で出し別けるのは便利だと思うが。

<picture>
  <source type="image/svg+xml" srcset="pyramid.svg">
  <source type="image/webp" srcset="pyramid.webp"> 
  <img src="pyramid.png" alt="4つの正三角形から構築された通常のピラミッド">
</picture>

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11