srcset属性
imgタグには通常、src属性に画像ファイルのURLを1つ指定します。
すると、当然ですが指定したURLの画像が読み込まれます。そして、src属性には複数のURLを指定することはできません。
つまり、imgタグのsrc属性だけでは、デバイスによる画像の切り替えは不可能ということになります。
そこで、必要となるのがsrcset属性と、sizes属性です。
まずsrcset属性から解説していきますが、srcset属性はsrc属性と違い、画像ファイルのURLを
,
で区切って、複数の画像ファイルのURLを指定できるというのが、大きな特徴です。
それではさっそく、srcset属性の指定の仕方を確認していきましょう。
srcset属性はsrc属性と違い、ただ画像ファイルのパス(URL)を記述すれば良いというわけにはいきません。
srcset属性には画像ファイルのパスの他、記述子=その画像の横幅(w)をセットで記述する必要があります。
<img src="sample.png"
srcset="
sample-300.png 300w,
sample-500.png 500w,
sample-1000.png 1000w"
alt="サンプル画像">
ここが勘違いしやすいポイントなのですが、画像の横幅(w)指定というのは画像を表示させたい横幅(width)や、画像を切り替えたいビューポートの幅(vw)ではないという点に特に注意が必要です。
HTMLやCSSに慣れていればいるほど、デバイスによって画像を切り替える=ビューポートの幅(vw)を指定する…という、意識になってしまいがちですが、srcset属性の指定においてはビューポートの幅は特に関係ありません。
単純に画像の横幅が500pxであれば、画像ファイルのパス 500wと指定すればよいという話です。
用語解説:ビューポート幅(vw)とは?
ブラウザがsrcset属性に指定された画像の大きさを解析し、デバイス(ブラウザ画面幅)に合わせて適切な画像を読み込む→Webページに表示させるという仕組みになっています。
スマホからWebページが閲覧されている場合、400w(横幅400px)ぐらいの画像なら問題なく表示できますから、通常であればスマホではそれぐらいの画像が自動的に選択されることになりますし、PC画面のフルサイズで閲覧されているなら1000w(横幅1000px)の画像を表示できるので、そちらが自動的に選択される…といった具合です。
つまり、基本的にブラウザが自動的に選択表示してくれるものであって、製作者側がスマホはこれ、PCはこれ…と指定するものではないということになります。
この点が今回の記事で最も重要なポイントです。
以下、参考までにブラウザの幅を動かして読み込まれる画像が変わっていく様子を撮影したものです。
POINT!
- ・srcset属性には複数の画像ファイルのパスを指定できる!
- ・srcset属性には画像ファイルのパスだけでなく、画像の横幅(w)をセットで記述する!
- ・srcset属性で指定する画像の横幅(w)は、実際の画像表示の横幅(width)やビューポート幅(vw)とは関係ない!
sizes属性
srcset属性で指定した複数の画像は、ブラウザがデバイスやブラウザ幅に合わせて自動的に振り分けて選択表示してくれるわけですが、このままでは振り分ける際の目安がデバイスやブラウザの幅の他にないという状態になってしまいます。
例えば1500w(1500px)の画像を表示できるPCモニターであっても、500pxの幅を画像表示の領域として、その領域に近いサイズの画像をブラウザに自動選択させたい…という場合もあり得ます。
このような時は、sizes属性を指定することでブラウザで自動選択される画像を、ある程度コントロールすることが可能です。
まずは基本的なsizes属性の指定方法を確認していきましょう。
<img src="sample.png"
srcset="sample-300.png 300w,
sample-500.png 500w,
sample-1000.png 1000w"
sizes="(max-width: 600px) 280px,
(max-width: 800px) 480px,
900px"
alt="サンプル画像">
上のサンプルコードでは、sizes属性の値を(max-width: 600px) 280px, (max-width: 800px) 480px, 900pxとしています。
この場合に読み込まれる画像は、メディアクエリ-で指定した条件におけるサイズ指定の、最も近いサイズの画像となります。
つまり上のサンプルの場合、デバイスやブラウザの幅が600pxまでの場合は280pxというサイズ指定なので、280pxに最も条件(サイズ)が近いsample-300.pngが読み込まれることになります。
サンプルのようにsizes属性を指定した場合の、条件別に読み込まれる画像は以下のようになります。
スマホでは表を横にスクロールできます。
|
sizes属性の指定 |
読み込まれる画像 |
600pxの幅まで |
(max-width: 600px) 280px |
sample-300.png 300w |
800pxの幅まで |
(max-width: 800px) 480px |
sample-500.png 500w |
上記以外 |
900px |
sample-1000.png 1000w |
また、CSSで別途調整しない限り、sizes属性で指定した数値が実際の表示サイズになるという仕様になっています。
よって、サンプルを例にすると画面幅が600pxまでであれば、sample-300.pngの画像が280pxの大きさで表示されることになります。
ということで、sizes属性の役割は以下の2つにまとめられます。
- 1)srcsetで指定された画像のうち、自動選択で読み込まれる画像のコントロール
- 2)自動選択で読み込まれた画像の表示サイズ調整
sizes属性ではメディアクエリーも使えて非常に便利なのですが、sizes属性の指定には注意点もあります。
まず一番気をつけたい点は、%(パーセント)が使えないという点でしょう。(pxやvwなどは使えます)
画面幅(vw)基準ではなく親要素の幅を基準に要素の幅を指定したい場合は%指定の方が便利ですが、sizes属性では%の指定が不可であるため、CSSによる調整が必要となります。
※%など様々な単位を用いた幅の指定方法は、こちらの記事を参照ください。
また、他の注意点としては、sizes属性による表示の幅指定よりも、CSSによる表示の幅指定が優先されるという点もあります。
WordPressをはじめとしたCMSでは画像が親要素からはみ出ないようにするため、デフォルトでimg { width: 100%; }といったCSS調整が加えられている場合も多いですが、そうなるとsizes属性による指定が表示サイズと一致しないことになります。
(とは言え、自動選択される画像をコントロールするという意味ではsizes属性を指定する意味はあります)
CSSの調整を無効化してsizes属性の値を優先させるには、imgタグにstyle属性を追加し、width: inherit;などで通常のCSSよりも優先度が高くなる形でwidthプロパティを初期化しておく必要があります。(下記サンプルコード参照)
<img src="sample.png"
srcset="sample-300.png 300w,
sample-500.png 500w,
sample-1000.png 1000w"
sizes="(max-width: 600px) 280px,
(max-width: 800px) 480px,
900px"
alt="サンプル画像"
style="width: inherit;">
ただし、style属性よりもさらに優先度が高くなる!important指定がされていたら、そちらの方が優先度が高くなるため注意が必要です。
%が使えないなどの不便性を考慮すると、sizes属性だけで画像の表示サイズをコントロールするのは、利便性が高くなくあまり現実的ではないと、個人的には思います。
画像の表示サイズは基本的にCSSで調整するのが良いでしょう。
POINT!
- ・sizes属性を指定することで、自動選択される画像や、画像の表示サイズをある程度調整できる!
- ・sizes属性による指定幅よりも、CSSによる指定幅の方が優先される!
- ・sizes属性では%が使えないなどの不便もあるので、sizes属性だけで全てコントロールするのは難しい!
高解像度ディスプレイの場合
iPhoneなどに搭載されているRetinaディスプレイをはじめとした高解像度ディスプレイでは、実際の画面サイズ幅よりも2倍以上大きな画像幅(w)の画像が自動選択されます。
例えば実際のスマホ画面の横幅(px)が400pxだとすると、srcset属性で複数指定した画像のうち、ブラウザの自動選択で読み込まれる画像は400w(400px)ではなく、800w(800px)以上のものになる…ということです。
なぜこのような現象が起こるのでしょうか?その答えを知るには、px(ピクセル)という単位の概念と高解像度ディスプレイの仕組みについて、ざっくり理解する必要があります。
本来、1pxは画面で表示可能な最小の単位ですから、1pxより小さな単位(0.5pxなど)は存在しないということになります。
しかし高解像度ディスプレイでは1pxをさらに分割することで、これを可能にしました。
つまり、物理的には400px分の幅しかなくとも、1pxを分割した分だけ表示可能なpx数が増えている…という状態ですね。
というわけで、物理的な画面の横幅は400pxしかなくとも、高解像度ディスプレイではその倍以上の画像の表示能力があることが分かったかと思います。
そして、ブラウザはデバイスのディスプレイ解像度も考慮した上でsrcset属性で設定された画像から画像を選択するため、デバイスの画面幅以上の画像が選択されるということが起こります。
通常はこの仕様はユーザーやWebサイト製作者にとって有利にはたらきます。高画質な画像を表示できるデバイスでは自動的にそちらを選択してくれるのですからね。
しかし、高解像度ディスプレイではないスマホ用(400px程度)とPC用(1000px程度)の2種類しか画像を用意していない場合、高解像度ディスプレイ搭載のスマホでは、スマホからの閲覧にも関わらず、PC用として用意した画像が表示されてしまう…ということになります。
こういったことがあるため、基本的にimgタグのsrcset属性による自動画像選択を利用してスマホ用の画像を縦長に作っておき、PC用の画像を横長に作っておくようなことは避けなければなりません。
横長の画像はPCからは見やすい反面、縦持ちのスマホからでは非常に小さく見えるため、PC表示を想定した横長の画像がスマホで表示されるのは避けたいところです。
もちろん、スマホで横長の画像を使うべきではないという意味ではなく、意図せずPC用の画像がスマホでも表示されてしまうのは望ましくないということです。
imgタグのsrcset属性だけで画像を自動で振り分ける際は、縦横比が同じ(内容も同じ)複数の画像をセットするのが基本です。
POINT!
- ・Retinaなどの高解像度ディスプレイでは、物理的な画面幅以上の画像サイズが読み込まれる!
- ・高解像度ディスプレイは1pxをさらに分割してきめ細やかな表示が可能であるため、このような現象が起こる!
- ・imgタグのsrcset属性のみでは自動で読み込まれる画像を完璧にコントロールするのは難しいため、縦横比や内容が同じ画像をセットしておくと良い!
src属性は保険にならない
srcset属性には複数の画像ファイルのパスを指定できますが、これに加えてsrc属性による画像のパス指定も行っておく必要があります。
というのも、IEなど古いブラウザはsrcset属性に対応していないため、どのような環境でも確実に画像を表示させるようにしておく必要があるからです。
(個人的には、いいかげんIEは捨て置いても良いと思いますが)
ただしここで重大な注意点があります。
それは、srcsetに対応しているブラウザでは、srcsetで読み込めなかった画像の保険としてsrc属性の読み込みが行われるわけではないという点です。
つまり、srcset対応ブラウザにおいてsrcset属性に指定したファイルのパス(URL)が間違っていると、src属性に指定したファイルのパスが正しくても画像は表示されないということになります。
というわけで、srcset属性に加えてsrc属性を指定するのはあくまでIEなどsrcset非対応のブラウザのためであり、万が一srcset属性の画像が読み込まれなかったときのための保険ではない…という点は必ず押さえておきたいポイントです。
ではsrcset非対応ブラウザを捨て置く(無視する)場合であれば、そもそもsrc属性は指定しなくても良いのでしょうか?
その答えはNOです。
srcset属性対応ブラウザであればsrc属性に指定された画像はどのみち読み込まれませんが、img要素のsrc属性は指定が必須である属性とされています。
よって、srcsetで読み込まれなかった場合の保険にはなりませんが、src属性も必ず指定しておくようにしておきましょう。
また、src属性による画像指定がsrcsetの保険にならない以上、最後の保険としてalt属性も合わせて指定しておくことをおすすめします。
用語解説:alt(オルト)属性とは?
POINT!
- ・srcsetが非対応のブラウザもあるので、src属性も合わせて指定しておこう!
- ・ただしsrcset対応のブラウザでは、srcset指定の画像が読み込まれない場合の保険としてsrc属性指定の画像が読み込まれるわけではない!
- ・最終的な保険はalt属性を指定しておくことで対処しよう!