継続は力なり#47
出力先に合わせて異なるサイズの画像を表示させる方法(続き)
ピクセル密度に合った画像だけを読み込ませる方法
それでは、img要素で指定する画像は常に2倍サイズのものを使用すればいいのかと言えば、そういうわけでもない
例として iPhone 8 Plus のピクセル密度は 2.6倍であり、iPhone X なら3倍である
それらを考慮に入れるのであれば、img要素には3倍サイズの画像を指定することになる
しかし、もしそのようにすれば、ピクセル密度が 1倍・2倍・2.6倍 の機器のユーザーは、常に不必要に大きな画像データを無駄に読みこまされることになる
そのような、問題を解決するために、HTML5.1からはimg要素に新しく「srcset属性」が追加された
これを使用することで、ピクセル密度別に用意した大きさの異なる画像をカンマ区切りで列挙して指定できる
そして、そのWebページを表示させる機器のピクセル密度に合った画像だけを読み込ませることができる
srcset属性には、値として「画像のURL」を指定するだけでなく、半角スペースで区切って「その画像が何倍のピクセル密度向けであるのか」も示す
ピクセル密度は数値に半角小文字の「x」をつけて表す
「2x」や「3x」のほか、「2.6x」のように小数を指定することもできる
srcset属性には、このようなURLとピクセル密度を示す書式のセットをカンマで区切っていくつでも指定できる
例
HTML
<img srcset="画像URL 画像幅w, 画像URL 画像幅w, 画像URL 画像幅w, ・・・"
sizes="単位付きの表示幅" src="画像URL" alt="〜">
⬇️
<img srcset="small.jpg 500w, medium.jpg 800w, large.jpg 1200w"
sizes="100vw" src="sample.jpg" alt="写真:夕暮れ">
「2x」のようにピクセル密度を設定した場合は、1倍の画像のみ「src属性」に指定したしかし「800w」のように画像の実際の幅を指定する場合には、用意してある全ての画像を「srcset属性」に指定する必要がある
src属性には「800w」のような幅は記述できないからである
そこで、全ての画像をsrcset属性内に「〇〇〇w」とともに記述し、その中の1つのファイルを重複してsrc属性にも指定する
このsrc属性の値は、srcset属性に未対応のブラウザのみ使用され、srcset属性に対応したブラウザはsrc属性を無視する
上記のサンプルでは、ここで初登場する「sizes属性」も指定されている
この属性は簡単に言ってしまえば画像の表示幅を指定する属性なのだが、width属性とは以下のような点で異なる
・CSSの単位をつけて指定する
・CSSの「calc( )」などの関数が使用できる
・メディアクエリの( )で示す条件と組み合わせて複数の幅が指定できる
詳しくはこの後のコラムで説明しますが、上記のサンプルで指定している「sizes="100vw"」という指定は、「表示領域全体の幅の100%で表示」という意味である
上記のサンプルをブラウザで表示させ、表示領域の大きさを変更すると、表示される画像も変化する
(画像が切り替わったことがわかるように、各画像には縦横のピクセル数を記入してある)
sizes属性の指定方法
sizes属性には、CSSの単位をつけた数値を単位で指定できるだけでなく、「メディアクエリーの( )で示す条件」と「表示させる幅」を半角スペースで区切ったものを、カンマ区切りで必要なだけ指定できる
その場合、それらの条件のうち最初に合致したものとセットになっている幅で表示されることになる
最後に条件つけないで幅だけを指定しておくと、どの条件にも合わなかった場合にその幅で表示される
<img sizes="(max-width: 799px) 100vw, (max-width:1199px) 800px, 1200px"
srcset="a.jpg 500w, b.jpg 800w, c.jpg 1200w, d.jpg 2400w" src="b.jpg"
alt="">
単位「vw」は、viewport と width の頭文字をとったもので、表示領域全体の幅の何パーセントであるかを示す単位
したがって、100vwであれば表示領域の横幅いっぱい(100%)、50vwであれば表示領域のちょうど半分の幅(50%)となる
また、sizes属性で幅を指定する際には、以下のようにCSS3の calc( ) 関数が使用できる
この例では、1200ピクセルから2vwを引いた値が幅となる
<img sizes="(max-width: 799px) 100vw, (max-width:1199px) 800px,
calc(1200px- 2vw)" srcset="a.jpg 500w, b.jpg 800w, c.jpg 1200w,
d.jpg 2400w" src="b.jpg" alt="">
calc( )関数の( )内には、単位をつけない数値も指定でき、そのような数値を単位もしくは「*(掛ける)」または「 /(割る)」で区切ってセットしたものを、「+(足す)」または「ー(引く)」で必要なだけ連結させて指定できる
calc(33vw - 100px)
calc(100vw/3 + 80px)
calc(100vw/3 + 80px - 2*1rem)