vol.71 srcsetで画像をレスポンシブやRetinaディスプレイに最適化

f:id:BOEL:20170718134020j:plain

こんにちは、Webエンジニアの佐藤です。
Web上で、ウィンドウサイズが変わった場合やRetinaディスプレイなどの高解像度の場合、その状況に対応した画像に自由に切り替えることができるsrcset。
今回は、画面解像度やウィンドウサイズによって最適な画像に切り替える方法、
srcsetの主なプロパティなど実際のコーディングにすぐ使えるサンプルを解説とともにまとめています。

 

srcsetでできること

・ウィンドウサイズによって画像を切り替える
・画面解像度に合わせて画像を切り替える

主に上記2つは、レスポンシブへの対応や、Retinaディスプレイなど高解像度のデバイスに対応することができます。

2017年7月14日現在のブラウザの対応状況としては、
Firefoxや、SafariChromeなどモダンブラウザでは問題なく動作しますが
IE全バージョン、Microsoft Edgeでは未対応です。

srcsetの記述のみではIEMicrosoft Edgeで画像が表示されなくなってしまいます。
srcset未対応ブラウザにも対応するため従来通りのsrcでの画像指定も必ず行いましょう。

 

srcsetサンプルコードと解説

ウィンドウ(ディスプレイ)サイズで画像を切り替える

<img src="middle.jpg"
srcset="large.jpg 1280w,middle.jpg 640w,small.jpg 320w"
sizes="50vw" alt="test">


・w属性
画像の横幅(オリジナル)、また画像を切り替えるウィンドウサイズ
sizesで画像表示幅を指定している場合、画像のオリジナル幅を指定していないと画像サイズが変わってしまう
sizesを使わない場合、表示切り替えポイントとしての使用で問題ない

・各ブラウザでの挙動
Safari:ウィンドウリサイズ+リロードで表示が切り替わる
Firefox:ウィンドウリサイズで表示が切り替わる
Chrome:最初に小さいウィンドウサイズで読み込んだ場合、
ウィンドウを大きくリサイズすると表示が切り替わるが ウィンドウを大きくリサイズした場合、もしくは大きいウィンドウで開いた場合、ウィンドウを小さくリサイズやリロードしても小さい画像に切り替わらない
表示すること自体に問題ないが、リサイズした際の挙動が不安定

・sizes
画像の表示サイズ横幅(vwのみ記述可能)
"(min-width:800px) 30vw,100vw" のようにメディアクエリを使って表示サイズを切り替えられる
カラム数を変えるときなどに使用する

w属性での指定は、後述するpictureを使ったウィンドウサイズでの画像切り替えと違い、w単位で画像の横幅を判定するディスプレイ依存の属性のため、画面解像度に合わせてRetinaディスプレイなどの場合は倍のサイズを読み込んでくれます。


例)PCで表示する画像:640px の場合、Retinaディスプレイで読み込まれる画像:1280px

※ブラウザでの動作は2017年7月14日現在のものです。

 

画面解像度で画像を切り替える

<img src="lar.png" srcset="middle.jpg 1x,large.jpg 2x" alt="test">


・1x、2x
Retinaディスプレイ対応、画面解像度で画像の切り替え
1x:1倍、2x:2倍
1.5、3、など必要に応じて指定すれば使える

※1x/2xはwの代わりとなるもので、wとの併用はできません。

 画像が表示されなくなります。

 

ウィンドウサイズで画像を切り替える

<picture>
<source media="(min-width:769px)" srcset="large.jpg">
<source media="(max-width:768px)" srcset="middle.jpg">
<source media="(max-width:320px)" srcset="small.jpg">
<img src="middle.jpg" alt="test">
</picture>

・picture、source
この組み合わせの場合のみ使える
ウィンドウリサイズで表示が切り替わる

・media
メディアクエリ、画像を切り替える画面幅の指定

・img
srcsetが使えない場合表示する画像を指定
※imgはsourceの後に記述しないと、sourceが読み込まれないため注意

・alt
sourceで指定された画像に共通のaltを入れる

 

ウィンドウサイズでの切り替えと、画面解像度での切り替えを組み合わせる

<picture>
<source media="(min-width:768px)" srcset="middle.jpg 1x,large.jpg 2x">
<source media="(max-width:767px)" srcset="small.jpg 1x,middle.jpg 2x">
<img src="middle.jpg" alt="test">
</picture>


・ media="(min-width:768px)" srcset="middle.jpg 1x,large.jpg 2x"
ウィンドウサイズが768以上の画面解像度が違う場合の2枚を指定

・ media="(max-width:767px)" srcset="small.jpg 1x,middle.jpg 2x"
ウィンドウサイズが767以下の画面解像度が違う場合の2枚を指定

 

backgroundでのRetinaディスプレイ対応

background-imageをcssのメディアクエリで表示を切り替える方法はよく知られていますが、同じくメディアクエリを使って、解像度で表示を切り替えることもできます。


@media only screen and (-webkit-min-device-pixel-ratio: 2){
body{background:url(large.jpg);}
}

画面の解像度を判定してbackgroundを切り替える
2以上の倍率で反映される

ChromeSafariなどwebkit系のブラウザでは上記で問題なく動作します。
device-pixel-ratioというのはもともとRetinaディスプレイが開発された際、Webkitが独自に開発したもののため、他のブラウザでは未対応です。
Firefoxなどのブラウザに対応させるには、以下のコードを併用します。
(min-resolution: 2dppx)


/* 例)*/
@media only screen and (-webkit-min-device-pixel-ratio: 2),(min-resolution: 2dppx){
body{background:url(large.jpg);}
}

 

まとめ

いかがでしたでしょうか。
機能としてはウィンドウサイズやRetinaディスプレイなどで画像を切り替えるという
単純なコードですが、srcsetとともに使用する属性や、注意点を簡単にまとめました。
なによりsrcsetのよいところは必要な画像だけを読み込んでくれるところ。
ウィンドウサイズや画面解像度別で多くの画像を用意し、指定しておいても実際に読み込むのはそのウィンドウやディスプレイに必要な1枚だけというのが魅力的です。
また画像の切り替えをするということは、それだけの画像を用意する必要があるということ。
バイス毎に最適な画像を表示できるようになりユーザーへの負荷が軽減されますが、
どうしても複数枚画像を用意するという手間はかかってしまいます。
さらにその画像を全て指定するとなるとHTMLのコードもどんどん煩雑になるため、簡単に切り替えができるからとあまり振り分けを細かくしてしまうのも考えものです。
将来的には、HTMLやCSSのみでも1枚の画像でさまざまなウィンドウサイズや画面解像度に対応できるようになり、画像を用意する手間、コードでの処理や記述などが軽減されるといいなと思います。