結論
- どの画像ファイルがダウンロードされるかは、
sizes
属性で決定される。 - その画像が表示される幅は、以下で決定される(優先順位の順番)。
- CSS での
width
プロパティ(優先順位 1位) width
属性sizes
属性
- CSS での
デバイスピクセル比 (DPR)
現在使用中のデバイスのデバイスピクセル比:
現在のウィンドウ幅:
各画像の幅: c-100.png
(100px), c-200.png
(200px), c-300.png
(300px), c-400.png
(400px)
実験1
コード
<img src="./c-400.png" loading="lazy"
alt="" id="img1"
srcset="./c-100.png 100w,
./c-200.png 200w,
./c-300.png 300w,
./c-400.png 400w"
sizes="200px">
結果
- sizes 属性を 200px にすることで、デバイスピクセル比 1 のデバイスでは、c-200.png が選ばれるようにしている。
実験2
コード
<img src="./c-400.png" loading="lazy"
alt="" id="img2"
width="300" height="278"
srcset="./c-100.png 100w,
./c-200.png 200w,
./c-300.png 300w,
./c-400.png 400w"
sizes="200px">
結果
- 300px で表示される。
- 300px にピッタリな c-300.png があるのに、c-200.png で 300px 表示することになる。
- width, height 属性でした通りのサイズで表示されるので、レイアウト・シフトはほぼ起きない。
実験3
コード
<img src="./c-400.png" loading="lazy"
alt="" id="img3"
width="300" height="278"
srcset="./c-100.png 100w,
./c-200.png 200w,
./c-300.png 300w,
./c-400.png 400w"
sizes="200px">
#img3 {
width: 400px;
height: auto;
}
結果
- c-400.png があるのに、c-200.png で 400px 表示することになる。
- 表示される幅・高さは CSS ファイルを読み込まないと分からないので、レイアウト・シフトが起きえる。
- 本ページでは、すぐに CSS ファイルの読み込みが始まるおかげでレンダーツリーの構築がブロックされ、その CSS ファイル内に画像の表示幅・高さの情報があるため、初期ペイントの時点で正確なサイズを空けておくことができ、レイアウト・シフトがほぼ起きない。たまたま起きないという見方ができる。
実験4: aspect-ratio を使う
コード
<img src="./c-400.png" loading="lazy"
alt="" id="img4"
srcset="./c-100.png 100w,
./c-200.png 200w,
./c-300.png 300w,
./c-400.png 400w"
sizes="200px"
style="aspect-ratio:400 / 185">
結果
aspect-ratio
は単独では意味がなく、width
もしくはheight
とセットで利用する。但し、sizes
属性とではセットで使えないらしい。もちろん、CSS でwidth
もしくはheight
を指定すれば効く。sizes
で決定した幅と、aspect-ratio
とを合わせて高さを計算させ、レイアウト・シフトを防ぐことはできないようだ。
実験環境
- OS: Windows 10
- Webブラウザ: Chrome 89.0