<img>
タグでレスポンシブ画像を実装する
HTMLの<img>
タグを使って、レスポンシブ画像(ブラウザーの横幅や解像度に応じて)を自動的に調整・実装するための、srcset
属性とsizes
属性の概念と使い方について解説します。
HTMLが提供するレスポンシブ画像技術
最近では、さまざまなデバイスからウェブを閲覧するのが一般的になっているため、レスポンシブウェブデザイン(Responsive web design)を実現する仕組みを理解し、扱うための技術を習得することは、ウェブデザインにおいて非常に重要な位置を占めるようになりました。
レスポンシブウェブデザインを実現するための代表的な方法として、CSSを使って実装する手法が挙げられます。もちろん、JavaScriptを併用することで、より洗練されたレスポンシブデザインを実現することも可能です。もう一つのアプローチとしては、HTMLが提供するレスポンシブ画像技術を利用する方法があります。この方法は、CSSによるレスポンシブデザインの手法と組み合わせて使用することで、より効果的に機能します。そしてこれは、レスポンシブウェブデザインを構成する技術の一部でもあります。
HTMLが提供するレスポンシブ画像技術には、2つの種類があります。
<img>
タグにsrcset
属性とsizes
属性を指定して使用する方法<picture>
タグ内で<source>
タグとsrcset
属性、media
属性、type
属性を使用する方法
本記事では、<img>
タグにsrcset
属性とsizes
属性を使用する方法について解説します。
<img>
タグでレスポンシブ画像を実装するためのsrcset
属性とsizes
属性の導入
<img>
タグの基本属性
<img src="image-path.jpg" width="200" height="500" alt="画像の代替テキスト">
上記のサンプルコードは、<img>
タグの基本属性をマークアップしたものです。
これらの属性の中でも、特にsrc
属性とwidth
属性に注目してください。
src
属性:読み込む画像ソースのパスを指定します。width
属性:読み込む画像ソースの幅(横サイズ)を指定します。
srcset
属性とsizes
属性は、<img>
タグでレスポンシブ画像を実装するために導入された属性です。
srcset
属性はsrc
属性と関連があり、sizes
属性はwidth
属性と関連しています。
srcset
属性:src
属性では実現できないブラウザのビューポート幅やディスプレイ解像度に応じたレスポンシブ画像ソースの指定のために導入された属性です。sizes
属性:width
属性では実現できないブラウザのビューポート幅とsrcset
属性で指定したレスポンシブ画像の幅との関係を指定するために導入された属性です。
ビューポート(viewport)はウェブブラウザ用語で、現在のウィンドウ(または全画面モードで文書を閲覧している場合は画面)に表示される文書の部分、すなわちウェブページが表示される領域を指します。
srcset
属性とsizes
属性によってレスポンシブ画像を実装するという意味
ブラウザのビューポート幅やディスプレイ解像度に応じて反応する画像ソースをsrcset
属性で指定し、ブラウザのビューポート幅とsrcset
属性で指定したレスポンシブ画像の幅との関係をsizes
属性で指定することでレスポンシブ画像を実装するという意味です。ここで、sizes
属性は必要がなければ使用しなくても問題ありません。この点については後ほど詳しく説明します。
<img>
タグのsrcset
属性
<img>
タグで使用するsrcset
属性は、ブラウザのビューポート幅やディスプレイ解像度に応じたレスポンシブ画像ソースを指定します。画像ソースは複数指定可能です。これはレスポンシブ画像のために、ブラウザが複数の画像の中から最適な画像を選択できるようにする属性であり、ディスプレイ解像度やブラウザのビューポート幅に応じて適切な画像をレンダリングすることで、ページの読み込み速度と画像の解像度の最適化を図るためのものです。
ご注意ください!srcset
属性は<img>
タグだけでなく、<picture>
タグの<source>
タグでも使用されます。
<picture>
タグの<source>
タグで使用するsrcset
属性はメディアクエリを利用して様々な状況に応じた異なる画像を選択するために使われますが、<img>
タグで使用するsrcset
属性は単にブラウザがディスプレイ解像度やビューポート幅に適した画像を選択するために使われます。
長く説明した<img>
タグのsrcset
属性について、要点をまとめてみます。
<img>
タグのsrcset
属性は、
1. ディスプレイ解像度や
2. ブラウザのビューポート幅に合わせた
最適なレスポンシブ画像ソースを設定するために使用される属性です。
srcset
属性の構文
構文の説明に入る前に、<img>
タグのsrcset
属性は、ブラウザのビューポート幅やディスプレイ解像度に応じたレスポンシブ画像ソースの指定のために導入された属性であることを忘れないでください。
<img>
タグのsrcset
属性の書式
<img
srcset="
レンダリング候補画像URL-1 レンダリング候補画像URL-1がレンダリングされるビューポート最大幅または最大ディスプレイ解像度1,
レンダリング候補画像URL-2 レンダリング候補画像URL-2がレンダリングされるビューポート最大幅または最大ディスプレイ解像度2,
レンダリング候補画像URL-3 レンダリング候補画像URL-3がレンダリングされるビューポート最大幅または最大ディスプレイ解像度3,
レンダリング候補画像URL-n レンダリング候補画像URL-nがレンダリングされるビューポート最大幅または最大ディスプレイ解像度n,
"
src="default.jpg"> <!-- srcsetが正しく設定されていれば、src属性は省略可能です -->
srcset
属性の構文は複雑に見えますが、上で示したように各行に属性値を分けて記述すれば理解しやすくなります。各値はカンマで区切ったリストで記述し、そのリストの各部分は3つの要素で構成されます。これからそれぞれの内容を見ていきましょう。
<img>
タグのsrcset
属性は、ブラウザに提示する画像のリストと、そのレスポンシブ画像の条件であるビューポート幅を基準にレンダリングすべき最大幅や最大ディスプレイ解像度を定義します。各カンマの前にこのように記述します。
- 画像ファイルのパス(レンダリング候補画像URL-n)
- 空白(スペース)
- レンダリング候補画像URL-nがレンダリングされるビューポート最大幅または最大ディスプレイ解像度n
まだ馴染みが薄く、難しく感じるかもしれません。次の3つの例を通して確認すると、より理解が深まるでしょう。
- ブラウザのビューポート幅に対応した画像ソースを指定する例のコード
- ディスプレイ解像度に対応した画像ソースを指定する例のコード
- ブラウザのビューポート幅に対応した画像ソースとディスプレイ解像度に対応した画像ソースを併せて指定する例のコード
ブラウザのビューポート幅に対応した画像ソースを指定する例のコード
<img>
タグのsrcset
属性書式において、ブラウザのビューポート幅に対応した画像ソースを指定する例のコード
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcsetが設定されていればsrc属性は無視されます -->
上記の例はブラウザのビューポート幅に対応した画像ソースを指定したものです。
heart-small-480px.jpg 480w
:ビューポート幅が480w
以下のとき、heart-small-480px.jpg
がレンダリングされます。heart-medium-700px.jpg 700w
:ビューポート幅が700w
以下のとき、heart-medium-700px.jpg
がレンダリングされます。heart-large-1000px.jpg 1000w
:ビューポート幅が1000w
以下のとき、heart-large-1000px.jpg
がレンダリングされます。
480w
、700w
、1000w
で使われているw
単位に注目してください。このw
単位は「w
descriptor」と呼ばれ、viewport width(ビューポート幅)の略称であり、長さの単位として換算するとpx
と同じ意味です。
480w
はビューポートの最大幅が480pxであることを意味します。つまり、ビューポート幅が480px以下という意味と同じです。これをCSSのメディアクエリで表現すると、@media (max-width: 480px)
と記述できます。つまり、heart-small-480px.jpg 480w
の意味は「ビューポート幅が480px以下の場合にheart-small-480px.jpg
がレンダリングされる」ということです。
700w
はビューポートの最大幅が700pxであることを意味します。つまり、ビューポート幅が700px以下という意味と同じです。これをCSSのメディアクエリで表現すると、@media (max-width: 700px)
と記述できます。つまり、heart-medium-700px.jpg 700w
の意味は「ビューポート幅が700px以下の場合にheart-medium-700px.jpg
がレンダリングされる」ということです。
1000w
はビューポートの最大幅が1000pxであることを意味します。つまり、ビューポート幅が1000px以下という意味と同じです。これをCSSのメディアクエリで表現すると、@media (max-width: 1000px)
と記述できます。つまり、heart-large-1000px.jpg 1000w
の意味は「ビューポート幅が1000px以下の場合にheart-large-1000px.jpg
がレンダリングされる」ということです。
srcset
属性が設定されている場合、src
属性は無視されます。
srcset
属性が設定されていても、条件に合致する画像がない場合は、最も近い条件の画像がレンダリングされます。例えば、ビューポートの幅が1800pxだと仮定します。先ほどの例を基にすると、条件に合致する画像はありません。この場合、heart-large-1000px.jpg 1000w
が最も近い条件となるため、heart-large-1000px.jpg
がレンダリングされます。
注意してください!
仮にビューポートの幅が500pxであるとします。
この場合、上記の例のコードでは、heart-medium-700px.jpg 700w
とheart-large-1000px.jpg 1000w
の両方が条件に合致します。どちらの画像がレンダリングされるのでしょうか?複数の条件に合致する場合は、属性の値をマークアップした順序(上から下、または左から右の順)で、最初に合致した条件の画像がレンダリングされます。つまり、heart-medium-700px.jpg 700w
がレンダリングされます。したがって、ビューポート幅を基準にw
ディスクリプタを使用する場合は、小さい値から順に指定する必要があります。そうしないと予期しない結果が発生する可能性があります。
必ず覚えておいてください!
仕様書では、レンダリング候補画像にw
ディスクリプタを使用する場合、ビューポート幅をレンダリング候補画像の実際の横サイズで指定することになっています。これは、レンダリング候補画像のサイズより大きいw
ディスクリプタ値が設定されていると、画像が拡大されて解像度が低下する問題(ピクセル化現象)が発生する可能性があるためです。
srcset属性に関する仕様書を参照してください。
ただし、これはレンダリングする画像がビューポート基準の幅の解像度を必要としない場合(CSSやwidth
属性でレンダリング画像の幅を調整する場合)には問題になりません。
ディスプレイ解像度に対応した画像ソースを指定する例のコード
<img>
タグのsrcset
属性書式でディスプレイ解像度に対する画像ソースを指定した例コード
<img
srcset="
heart-small-480px.jpg 1x,
heart-medium-700px.jpg 2x,
heart-large-1000px.jpg 3x
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcsetが設定されている場合、src属性は無視されます -->
まずはディスプレイ解像度について説明します。
ディスプレイ解像度は専門用語で「画像密度(画像デバイスのピクセル比、Image Pixel Density)」とも呼ばれ、ディスプレイ装置のピクセル密度を示す値です。これは画像のピクセル数と画像の幅・高さの比率を表します。画像密度が高いほど、画像のピクセル数が多くなり、より鮮明に見えます。
一般的にブラウザで使用されるデバイスピクセル比は1x、2x、3xなどで表示されます。デバイスピクセル比はディスプレイの物理的なピクセル数とCSSピクセル数の比率を示し、高解像度ディスプレイの場合は2x以上のピクセル比を持つことがあります。モバイルデバイスや高解像度(Retina)ディスプレイはディスプレイ解像度が高いです。
上記の例は、ディスプレイ解像度に対応した画像ソースを指定したものです。
heart-small-480px.jpg 1x
:ディスプレイ解像度が1x
以下の場合にheart-small-480px.jpg
がレンダリングされます。heart-medium-700px.jpg 2x
:ディスプレイ解像度が2x
以下の場合にheart-medium-700px.jpg
がレンダリングされます。heart-large-1000px.jpg 3x
:ディスプレイ解像度が3x
以下の場合にheart-large-1000px.jpg
がレンダリングされます。
1x
、2x
、3x
で使用されている x
単位に注目してください。この x
単位は「x
descriptor(ディスクリプタ)」と呼ばれ、倍率を意味します。1x
は1倍、2x
は2倍、3x
は3倍を表します。たとえば 1x
の場合、画像のピクセル数は実際の表示サイズと同じです。一方で 2x
の場合は、画像のピクセル数が表示サイズの2倍となる高解像度の画像を意味します。
ディスプレイの解像度に応じて画像ソースを設定することは、主に高解像度ディスプレイで利用されるのが一般的です。高解像度ディスプレイはピクセル密度が高く、通常のディスプレイよりも多くのピクセルを使って画面を表示します。そのため、このようなディスプレイでは高解像度の画像を使用することで、より鮮明で高品質な画像を提供することが望ましいとされています。たとえば、モバイルデバイスやApple社のディスプレイなどが該当します。Appleは「Retinaディスプレイ」と呼ばれる高解像度ディスプレイを多くの自社製品に搭載しています。
ブラウザのビューポート幅に対応した画像ソースとディスプレイ解像度に対応した画像ソースを併せて指定する例のコード
<img>
タグの srcset 属性の書式において、ブラウザのビューポートの幅に対応した画像ソースと、ディスプレイの解像度に対応した画像ソースの両方を指定する例のコード
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 2x,
heart-large-1000px.jpg 1000w
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcset が設定されている場合、src 属性は無視されます -->
上記の例のように、<img>
タグの srcset 属性の書式では、ブラウザのビューポートの幅に対応した画像ソースと、ディスプレイの解像度に対応した画像ソースの両方を併せて指定することができます。
しかし、次の例は誤ったコードです。
<img>
タグの srcset
属性の書式において、w
ディスクリプタと x
ディスクリプタを同時に1つのレンダリング候補画像に適用することは、正しい構文ではありません。
<img
srcset="
heart-small-480px.jpg 480w 1x,
heart-medium-700px.jpg 700w 2x,
heart-large-1000px.jpg 1000w 3x
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcset が設定されている場合、src 属性は無視されます -->
残念ながら、w
ディスクリプタと x
ディスクリプタを同じ画像候補に同時に適用することは、正しい構文ではありません。各画像候補には w
ディスクリプタか x
ディスクリプタのいずれか一方だけを使用する必要があります。ブラウザはこれらのディスクリプタを利用して画像を選択するため、ディスクリプタを正しく使うことが重要です。
<img>
タグのsizes
属性
<img>
タグで使用するsizes
属性はメディアクエリ(Media Query)を用いてw
ディスクリプタを使ったsrcset
属性で提供されるレンダリング候補画像の利用方法を定義するために使われます。
したがって、sizes
属性はsrcset
属性なしで単独で使用することはできず、srcset
属性と共に使用されます。
sizes
属性の構文
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
sizes="
(max-width: 幅) 幅,
(max-width: 幅) 幅,
幅
...
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcset が設定されている場合、src 属性は無視されます -->
- 画像の幅を表すコンマで区切られた一つ以上の文字列です。それぞれの文字列は以下の構成要素で成り立っています。
- メディアクエリ(Media Query):最後のリストでは省略可能です。
- 画像の幅:
%
、cm
、mm
、in
、pt
、pc
などの相対的な単位やその他の特定の単位です。したがって、sizes
属性では相対的な単位や特定の単位を使用できず、ビューポートを基準とした相対的な単位(px` を含む)と共に使用する必要があります。
以下の例を通して見てみましょう。
<img>
タグの srcset
属性書式で、ブラウザのビューポート幅に対応した画像ソースを指定した例コード
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
sizes="
(max-width: 480px) 480px,
(max-width: 700px) 700px,
1000px
"
src="heart-large-1000px.jpg"
alt="ハート"> <!-- srcsetが設定されている場合、src属性は無視されます -->
(max-width:480px)480px
:ビューポートの幅が480px以下の場合srcset
属性で設定された480w
の値に最も近いレンダリング候補画像が表示されますただし候補画像の値は480w
以下でなければなりませんここではheart-small-480px.jpg
がレンダリングされます。(max-width:700px)700px
:ビューポートの幅が700px以下の場合srcset
属性で設定された700w
の値に最も近いレンダリング候補画像が表示されますここではheart-medium-700px.jpg
がレンダリングされます。- 条件に関係なく最も近い
w
ディスクリプタの値がレンダリングされます。ここではheart-large-1000px.jpg
がレンダリングされます。
ブラウザ互換性
属性 |
デスクトップ Chrome
|
デスクトップデスクトップ Edge
|
デスクトップ Firefox
|
Safari
|
---|---|---|---|---|
srcset
|
34 | 18 | 38 | 8 |
sizes
|
38 | 12 | 38 | 9.1 |
参考資料
以下の参考文献をご覧ください。本記事で扱えなかったレスポンシブ画像に関連する属性について、有益な情報が多数掲載されています。
ほとんどの参考文献は非常に権威があり、世界中のウェブ開発者が参照している資料です。