HTML講座 / srcset・sizes・pictureでレスポンシブ画像を作る
レスポンシブ画像は、表示条件に合う画像ファイルをブラウザーが選べるようにする仕組みです。同じ構図の解像度を選ぶ場合はsrcsetとsizes、画面幅によって切り抜き方を変える場合はpictureを使い分けます。
実習用の画像をそろえる
この実習は、同じ湖の写真の幅480・960・1600ピクセル版と、800×800ピクセルの正方形版を使います。画像の挿入で使う画像と同じ系列です。原文に掲載されているファイルへのリンクは次のとおりです。
ファイル名を変えずにHTMLと同じフォルダーに保存します。三つの横長画像は構図と比率が同じで、正方形版は狭い画面で木を見せやすい別の構図です。解像度の比較と構図の比較を混同しないようにします。
srcsetとsizesで解像度を選ぶ
480wなどのw記述子は各ファイルの実際の横幅です。sizesは画面の条件ごとに画像が表示される予定の幅をCSSピクセルで伝えます。次の例は800ピクセル以下ではほぼ画面幅、それ以上では800ピクセルの表示を想定しています。
<img class="example-fluid"
src="html-image-sample-lake-tree-960-v1.webp"
srcset="html-image-sample-lake-tree-480-v1.webp 480w,
html-image-sample-lake-tree-960-v1.webp 960w,
html-image-sample-lake-tree-1600-v1.webp 1600w"
sizes="(max-width: 800px) 100vw, 800px"
alt="A tree on a small island in a lake, with mountains beyond"
width="1600" height="900">
.example-fluid {
display: block;
width: 100%;
max-width: 800px;
height: auto;
}
HTMLはbody、CSSはheadのstyleかCSSファイルへ入れます。srcはフォールバックです。実際のレイアウトが違うならsizesも直します。ブラウザーは画素密度やズームも考慮するため、狭い画面だから必ず480版になるとは限りません。
固定表示幅では1x・2xを使える
幅480 CSSピクセルで固定表示する例では、密度別に1xと2xを提示できます。この方式ではsizesを併用しません。
<img class="example-fixed"
src="html-image-sample-lake-tree-480-v1.webp"
srcset="html-image-sample-lake-tree-480-v1.webp 1x,
html-image-sample-lake-tree-960-v1.webp 2x"
alt="A tree on a small island in a lake, with mountains beyond"
width="480" height="270">
.example-fixed {
display: block;
width: 480px;
height: auto;
}
このCSSは固定幅なので、それより狭い親領域でははみ出す場合があります。可変幅にしたいなら前のwとsizesを使う例へ戻ります。一つのsrcsetでwとxを混在させないようにします。
pictureで構図を変える
600ピクセル以下では正方形、それより広い場合は横長の画像を使う例です。sourceの条件と、フォールバックのimgを組み合わせます。代替テキストはimgに書きます。
<picture class="example-picture">
<source media="(max-width: 600px)"
srcset="html-image-sample-lake-tree-square-800-v1.webp"
width="800" height="800">
<img src="html-image-sample-lake-tree-960-v1.webp"
alt="A tree on a small island in a lake, with mountains beyond"
width="960" height="540">
</picture>
.example-picture img {
display: block;
max-width: 100%;
height: auto;
}
構図の選択と表示幅の調整は別です。CSSで親領域に収め、比率を保ちます。記事中の静止画像が正方形であっても、それだけで画面幅に応じて切り替わる例になったとは言えません。実習用HTMLで実際の選択を確認してください。
currentSrcと通信記録で確認する
headにmeta name="viewport" content="width=device-width, initial-scale=1"を入れ、必要な画像とHTMLを保存します。ブラウザーの開発者ツールのNetworkでキャッシュを無効にし、画面幅を変えて再読み込みしてください。Consoleでは次のように現在選択されたURLを調べられます。
document.querySelector('.example-fluid').currentSrc
document.querySelector('picture img').currentSrc
pictureは600ピクセルと601ピクセルで比較します。srcsetは同じ幅でも画素密度やズームで結果が変わります。大きい画像を一度読み込んだ後に画面を狭めても、すぐ小さい画像へ替わらない場合があるため、キャッシュ条件をそろえて比較します。
解像度選択と構図変更を分けて検証する
| 目的 | 仕組み | 確認する点 |
|---|---|---|
| 可変幅で同じ構図 | wとsizes | CSSの表示幅とsizesの対応、currentSrc |
| 固定幅で同じ構図 | 1x・2x | 画素密度と候補ファイル。表示幅はCSS側で指定 |
| 画面幅で別の構図 | pictureとmedia | 600pxと601pxで切り抜き方を比較 |
ビューポートはレイアウトに使うブラウザーの表示領域です。CSSピクセルと画像の実ピクセル、端末の物理ピクセルは同じとは限りません。この違いを分けて考えると、同じ幅で違う候補が選ばれる理由を調べやすくなります。
意図しない画像が選ばれる場合
各wの値がファイルの実寸と一致するか、sizesが実際のCSS幅に合っているかを確認します。同じ構図の縮小画像と別の切り抜き画像を混ぜて解像度選択だけで切り替えようとしないでください。条件、キャッシュ、画素密度を一つずつ変え、比較後は元の設定へ戻します。MDNのレスポンシブ画像とHTML標準の画像の解説で選択規則を確認できます。









