「スマホでは縦長、PCでは横長の画像を出したい」「対応ブラウザには WebP、ダメなら JPEG を出したい」——こうした画像の出し分けを HTML だけで実現できるのが picture 要素です。複数の候補から、ブラウザが条件に合う1枚を選んで表示してくれます。この記事では picture と source の使い方を、よく使う2つのパターンに分けて解説します。
目次
picture 要素とは
picture は、複数の画像候補(source)と、最終的なフォールバック用の img を内側に持つ要素です。ブラウザは source を上から順に見て、条件に合う最初の1つを採用します。どれにも合わなければ img が表示されます。
<picture>
<source ...> <!-- 候補1(条件に合えばこれ) -->
<source ...> <!-- 候補2 -->
<img src="..." alt="..."> <!-- どれも合わないときの保険 -->
</picture>
大事なのは、img を必ず最後に置くことです。実際に表示されるのは img 要素で、alt や width などの属性も img に書きます。source はあくまで「条件付きの差し替え候補」を示すだけです。
パターン1:画像のフォーマットを出し分ける
source の type 属性に画像フォーマットを指定すると、そのフォーマットに対応しているブラウザだけがその画像を使います。新しい WebP や AVIF を優先しつつ、未対応ブラウザには JPEG を出す、という定番の使い方です。
<picture>
<!-- 対応していれば AVIF を使う -->
<source srcset="photo.avif" type="image/avif">
<!-- 次に WebP を使う -->
<source srcset="photo.webp" type="image/webp">
<!-- どちらも未対応なら JPEG(保険) -->
<img src="photo.jpg" alt="海辺の風景" width="800" height="500">
</picture>
ブラウザは上から順にチェックし、対応しているフォーマットの最初の1枚を表示します。AVIF・WebP は JPEG より軽いことが多いので、表示速度の改善につながります。type には image/avif / image/webp / image/jpeg のように MIME タイプを書きます。
パターン2:画面幅で画像そのものを変える(アートディレクション)
source の media 属性にメディアクエリを書くと、画面幅に応じて違う画像を表示できます。単に同じ画像を縮小するのではなく、「スマホでは被写体に寄せたトリミング、PC では引いた構図」のように構図ごと変えることができます。これをアートディレクションと呼びます。
<picture>
<!-- 画面幅 600px 以下では縦長の画像 -->
<source media="(max-width: 600px)" srcset="hero-sp.jpg">
<!-- それより広ければ横長の画像 -->
<source media="(min-width: 601px)" srcset="hero-pc.jpg">
<img src="hero-pc.jpg" alt="新商品のメインビジュアル" width="1200" height="600">
</picture>
条件に合う最初の source が選ばれるので、media の指定は記述の順番が重要です。ウィンドウ幅を変えてリロードすると、表示される画像が切り替わるのを確認できます。
picture と img の srcset はどう使い分ける?
「画像の出し分け」というと img の srcset 属性も思い浮かびます。役割が違うので、目的で使い分けます。
| やりたいこと | 使うもの |
|---|---|
| 同じ画像を、画面の解像度・幅に応じてサイズ違いで出す | img の srcset / sizes |
| フォーマット(WebP / AVIF)で出し分ける | picture + source type |
| 画面幅で構図の違う別画像に変える | picture + source media |
ざっくり言うと、「中身は同じでサイズだけ変えたい」なら img srcset、「フォーマットや構図そのものを変えたい」なら picture です。なお picture 内の source でも srcset と sizes を併用でき、両者は組み合わせて使えます。
うまく表示されないときのチェックポイント
img を入れ忘れている
もっとも多いのが、img を書き忘れているケースです。picture の中で実際に描画されるのは img です。これが無いと何も表示されません。source だけで完結させようとしないように注意します。
source の順番が逆になっている
ブラウザは「条件に合う最初の source」を採用します。たとえば (min-width: 601px) を先に書くと、広い画面でそちらが先に一致してしまい、狭い画面用の指定が効かないことがあります。条件が重ならないように、または意図した優先順で並べましょう。
レイアウトのガタつきを防ぐ
画像の読み込み前後でレイアウトがずれる(ガタつく)のを防ぐため、img に width と height を指定しておきましょう。CSS で max-width: 100% などを併用すると、レスポンシブにしつつ表示領域を確保できます。
まとめ
picture 要素は、複数の候補からブラウザに最適な1枚を選ばせる仕組みです。
sourceを上から順に評価し、条件に合う最初の画像を表示するtypeでフォーマット(WebP / AVIF)を出し分け、未対応にはimgでフォールバックmediaで画面幅に応じて構図の違う画像に差し替えられる(アートディレクション)- 実際に表示されるのは
img。altやwidth/heightはimgに書き、最後に必ず置く
サイズ違いだけなら img の srcset、フォーマットや構図の出し分けなら picture、と覚えておくと迷いません。詳しい仕様は MDN の picture 要素 も参考にしてください。