HTMLの<picture>
タグを使えば、CSSやJavaScriptを使わなくても、画像をレスポンシブに切り替えることができます。
<picture>
はHTML5で登場しましたが、IEをのぞけば、すべての主要ブラウザで使用できます。
ブラウザ対応状況へスキップ
pictureタグでできること
<picture>
により実現できることは次の2つです。
- 画面幅によって、表示する画像を切り替える
- ブラウザが対応していない形式の画像なら、別の画像を表示する
また、<picture>
を使えば「WebP形式の画像に対応していないブラウザなら、PNG画像を表示する」といった出し分けも可能になります。
pictureタグの使い方
具体的な使い方を解説していきます。
sourceとimgタグと使う
<picture>
タグは、複数の<source>
と、1つの<img>
を囲う形で使います。
<picture>
<source srcset="候補1の画像URL" 属性 />
<source srcset="候補2の画像URL" 属性 />
<img src="候補4の画像URL" alt="~" />
</picture>
👆それぞれに表示する画像候補のURLを指定します。この中からどれか1つの画像が表示されます。<img>
は1つだけですが、<source>
はいくつ入れてもOKです。
条件に当てはまる画像1つだけが表示される
ブラウザは以下のような流れで、<source>
と<img>
のうちから表示する画像を1つ選びます。
表示する画像の選ばれ方
<source>
を上から1つずつ順番に読んでいく<source>
の属性に指定された条件を読む- 条件に当てはまれば、その画像を表示。当てはまらなければ、下の
<source>
へと進む <source>
のどれにも条件が当てはまらなければ<img>
を表示する
つまり👇このような優先順位で判定されます。
表示される優先順位
<picture>
<source .../><!-- 🥇優先順位1 -->
<source .../><!-- 🥈優先順位2 -->
<source ... /><!-- 🥉優先順位3 -->
<img ... /><!-- 😿どれも当てはまらなければimgを表示 -->
</picture>
sourceタグの属性を指定する
<source>
タグの属性で「どの場合に、どの画像を表示するか」という条件を指示します。
画像URL(srcset)必須
<source srcset="画像のURL" />
▼例
<source srcset="/learning/images/example.png" />
👆srcset
には画像URLを指定します。<img src="○○">
と同じようにURLを入れればOKです。条件に当てはまったときは、ここに指定した画像が表示されます。
メディアクエリ(media)
<source srcset="画像のURL" media="メディアクエリ" />
▼例
<picture>
<source srcset="~" media="(min-width: 1000px)"/><!-- 幅1000px以上なら表示 -->
<source srcset="~" media="(min-width: 700px)"/><!-- 幅700px以上なら表示 -->
<source srcset="~" media="(min-width: 500px)"/><!-- 幅500px以上なら表示 -->
<img ... /><!-- それ以外で表示 -->
<picture>
👆media
属性には、メディアクエリ(画面幅に応じた条件)を指定します。(min-width: ○○px)
と書けば「画面幅が○○px以上なら…」という意味になります。画面サイズに応じて画像を切り替えたいときに使用します。
😺さきほど説明した通り<source>
は上から順番に読み込まれていくので、配置する順番に注意しましょう。条件に合致する<source>
が見つかった時点で画像は表示され、他の画像は読み込まれません。
画像の形式(type)
<source srcset="画像のURL" type="画像の形式" />
▼例
<picture>
<source srcset="/sample.webp" type="image/webp"/>
<img src="/sample.png" /><!-- ブラウザがwebpに対応していない場合に表示 -->
<picture>
👆type
属性には、画像の形式を「MIMEタイプ」で指定します(例:type="image/webp"
)。JPEG、PNG、GIFは全ブラウザで対応しているため、<source type="○○">
に指定する意味はありません。WebPなど、未対応ブラウザがある画像を挿入したい場合に指定します。
😺WebPはGoogleが開発している次世代の画像形式です。「高い画質を保ちつつ、軽量」と優れているのですが、未対応のブラウザがあります(WebPの対応ブラウザ)。<picture>
を使えば、対応ブラウザでのみWebP画像を表示できるわけですね。
レスポンシブに別画像に切り替えるサンプル
ここからは具体的なサンプルコードを紹介します。まずは<picture>
タグを使って画面幅に応じて、別の画像を表示するサンプルです。
HTML
<picture class="sample">
<source srcset="画像1URL" media="(min-width: ○○px)" /><!-- ○○px以上で表示する画像 -->
<source srcset="画像2URL" media="(min-width: △△px)" /><!-- △△px以上で表示する画像 -->
<img src="画像3のURL" alt="サンプル画像"/><!-- それ以外の場合に表示する画像 -->
</picture>
👆このように書くことで、画面幅に応じて、別の画像が表示されます。<source>
は、条件分岐に必要な数だけ増やしましょう。画像は必要になったときに読み込まれるため、パフォーマンス上の心配は不要です。
画像ごとにスタイルを変える
それぞれの画像ごとに、表示幅(width)や装飾を変えたい場合には、CSS側で合わせてメディアクエリを指定すればOKです。
CSS 画像ごとに幅などのスタイルを変える
.sample img {
max-width: 100%;
width: 200px;
}
/* 画面幅が800px以上のとき */
@media only screen and (min-width: 800px) {
.sample img {
width: 400px;
}
}
/* 画面幅が1200px以上のとき */
@media only screen and (min-width: 1200px) {
.sample img {
width: 600px;
border: solid 3px bold; /* 例:1200px以上でのみ線で囲む */
}
}
👆<source>
の画像であっても、img { ~ }
という書き方でスタイルを適用できます。逆にsource { ~ }
というように<source>
自体にCSSを適用しようとしても、うまく効きません。
CSSのdisplay: none
とメディアクエリを使えば、画面幅に応じて別画像に切り替えることができます。「特定の幅以上だったら画像Aを表示して、画像Bを非表示にする」というような手法ですね。
この方法だとHTMLやCSSが見づらくなるだけでなく、画面幅にかかわらず、どちらの画像も読み込まれてしまうため、パフォーマンス上の問題があります(display: none
は画面上で隠すだけなので、画像自体は読み込まれてしまいます)。
<picture>
でレスポンシブに画像を切り替える方法なら、必要になった画像しか読み込まれません。
対応ブラウザでのみWebP画像を表示するサンプル
HTML
<picture>
<source srcset="WebP画像のURL" type="image/webp"/>
<img src="WebP未対応のときに表示する画像のURL" />
<picture>
👆WebP画像をページに貼りたい場合は、このように書きましょう。<img>
に「WebP未対応だった場合用の画像」を指定しておくわけですね。
なお、<source>
のWebP画像が表示される場合も、適用されるCSSは<img>
に対するCSSと変わりません。つまり、表示される画像のスタイルは同じです。WebP画像用に別途CSSを指定する必要はありません。
関連リンク
画面(ビューポート)の幅に応じて、別の画像を表示することが可能になります。これは「レスポンシブ画像」や「レスポンシブイメージ」などと呼ばれます。
👉デモページ