ビューポートや解像度など、デバイスに応じて最適な画像を表示させるレスポンシブ画像。WordPressなど自動でやってくれるものもあるので、しばらく自分で触ってなかったら記憶が曖昧になってしまったので、まとめておきます。
srcsetによる画像選択肢の提供
srcset属性を利用することで複数の画像を選択肢として与え、どの画像を選択するかブラウザに判別させます。
画像URLの後ろに「幅」を指定します。実画像の横幅と認識しておけば良いです。pxではなく「w」を単位に使います。以下例
<img srcset="/sample-320.jpg 320w,
/sample-640.jpg 640w"
src="/sample.jpg"
width="960" height="600" alt="sample">
srcsetが便利なのは「選択されなかったファイルはダウンロードされない」という点です。モバイル端末ならデータサイズも小さくなるので表示速度の改善にもつながります。また、サイズだけでなく画質の最適化も行います。それが次の「Retinaへの対応」です。
Retinaディスプレイへの対応
画質へのこだわりから、最近はスマートフォン中心にRetinaディスプレイがどんどん増えています。
Retina(レティナ、レティーナ)とは網膜のことで、「画素が細かく人間の目で識別できる限界を超えている」ことから命名されたそうです。(が、その後誇大広告だと指摘されていたはず。その後は知らない)
Retinaディスプレイをざっくり説明すると、
従来320pxの幅には320pxサイズの画像を表示していました。そこに2倍、あるいは3倍のサイズの画像を使うことで、キメの細かい綺麗な画像を表示できる というものです。
話をsrcsetに戻しますが、srcset指定はブラウザの解像度も考慮してくれるので、特別な記述をしなくても非Retina非ディスプレイには等倍の画像サイズを。Retinaディスプレイにはデバイスピクセル比に応じたサイズの画像を選択してくれます。
簡単なテストページを作ったので、アクセスしてもらうと現在のディスプレイがRetinaかどうか、どのサイズの画像が表示されているかが分かります。
sizes属性による、表示幅の指定
ブラウザがsrcsetで用意された画像からどれを選ぶか考えるとき、表示サイズ = 100vw(画面幅いっぱい)で計算しています。
ですが実際には、「モバイルなら100vw、タブレットは50vw(半分)、PCでは960pxで表示したい」のようになるのがほとんどです。そこでsizes属性で、表示させるサイズを指定します。以下サンプル
<img sizes="(max-width:500px) 100vw,
(max-width:1000px) 50vw,
960px"
srcset="/sample-320.jpg 320w,
/sample-640.jpg 640w"
src="/sample.jpg"
width="960" height="600" alt="sample">
このサンプルだと、スクリーンサイズが500px以下では100vw、1000px以下では50vw、それ以上では960pxで画像を表示するものとして、そのサイズに応じた画像を選択するようになります。(ブレイクポイントは適当です)
次章で述べるアートディレクションやwebPやavif表示など、異なる画像やファイル形式を使わない限りは、srcsetで対応すべきとされています。
解像度による振り分けだけしたいときは「x」
画像幅のwではなく、「x」という単位を使って、解像度2倍ならA画像、3倍ならB画像という指定もできます。どの端末でも大きさが変化しない小さな画像などはxの書き方でも良いかも知れません。以下例
<img srcset="/sample-300.jpg 1x, // 解像度1倍のとき表示させる
/sample-600.jpg 2x" // 解像度2倍
src="/sample.jpg"
width="300" height="200" alt="sample">
違うサイズや違うファイル形式の選択肢を用意する
たとえば、PCで横幅いっぱいのパノラマ写真を、スマホでそのまま縮小表示してしまうと貧相な画像になってしまいます。モバイルでは縦長の画像表示がベストとなるでしょう。
写真を背景画像に設定してCSSで表示範囲を変更する方法もありますが、違うサイズの画像をそれぞれ用意して、sourceタグで振り分ける方法があります(アートディレクション)。
背景画像の位置調整と異なり、小さい画像を用意することでデータサイズの削減にもなります。
画像のsourceなのでpictureタグで囲みます。以下サンプル
<picture>
<source srcset="/sample-smart.jpg" media="(max-width:500px)">
<source srcset="/sample-tablet.jpg" media="(max-width:1000px)">
<source srcset="/sample-pc.jpg">
<img src="/sample-pc.jpg" width="1920" height="400" alt="sample">
</picture>
*注 media属性を使用するときは、sizes属性を使用できません。
media属性で適切な画像が振り分けられます。注記の通りmedia属性とsizes属性は併記できませんが、よく考えれば当たり前の話です。
webP画像など、ファイル形式で振り分けるときはtype属性で振り分けます。
<picture>
<source type="image/webp" srcset="/sample.webp">
<img src="/sample.jpg" width="300" height="200" alt="sample">
</picture>