分室利用者のY.Nです。
前回の記事『レスポンシブイメージの考察』の続きについて書きたいと思います。第2回である今回は、ビューポートとデバイスピクセル比に応じて、最適な画像を読み込む手法について書いてみたいと思います。
もし興味がありましたら、ご覧いただけたらと思います?
従来の記述を振り返る
この弊社ブログで画像を載せる(img
タグを書く)場合、従来の記述方法であれば、おそらく、次のような事を考えて、画像の幅を決めると思います。
- ブラウザでCtrl+Shift+Mを押下し、レスポンシブデザインモードを起動
- Webページ枠の左右をマウスでドラッグし、ひとまず1200pxまで広げる
- 徐々に狭めていくと、次のような事が分かる
- 画面幅1042px以降は、画像幅が680pxの固定になっている
- 画面幅769~1041pxは、画像幅が501.9~679.5pxの可変になっている
- 画面幅320~768pxは、画像幅が307.2から737pxの可変になっている
- 一番大きい画像幅は737pxなので、この幅で決定 (画像は拡大すると汚くなる為)
しかし、これでは、無駄な通信が発生する場合があります。例えば、画面幅が320pxの時に、画像幅737pxを読み込む、というケースです。無駄な通信が発生するという事は、ページ読み込みが遅くなってしまいますので、ユーザは離脱しやすくなり、極端に遅いとSEO的にもマイナス評価になってしまいます。
また、Retina等のデバイスピクセル比が2以上の場合にも対応できておらず、iPad等のタブレット(仮に画面幅を768pxとする)で見た時に、画像がボヤけてしまいます。
srcsetとsizes属性とは
HTML 5.1では、
タグに、img
srcset
とsizes
属性を書けるようになりました。
srcset
属性は、画像の候補を書く事ができ、前回の記事のように、倍率で指定(例: srcset="img-x2.png 2x"
)する事もできるのですが、今回は、w
というファイルの画像幅を使って書いていきます。なお、倍率とファイル画像幅は併記する事は出来ません。
sizes
属性は、ブレイクポイントと画像の表示サイズを書いていきます。例えば、画面幅768pxまでは表示したい画像幅が100vwで、それ以降の画面幅(769px以上)では表示したい画像幅を640pxにしたい、という場合であればsizes="(max-width: 768px) 100vw, 640px"
という書き方になります。
srcsetとsizes属性を使った記述
Retina等を考慮しない場合
この弊社ブログで画像を載せる(img
タグを書く)場合を考えてみます。画面幅と画像幅に関しては、以下のような仕様になっている事を思い出して下さい。
- 画面幅1042px以降は、画像幅が680pxの固定になっている
- 画面幅769~1041pxは、画像幅が501.9~679.5pxの可変になっている
- 画面幅320~768pxは、画像幅が307.2から737pxの可変になっている
これらを考慮すると、次のような書き方ができると思います。
See the Pen Mqeeoy by sp-sephiroth (@sp-sephiroth) on CodePen.
まず、sizes
属性の値から説明します。
sizes
属性値の1行目の(max-width: 768px) 96vw
というのは、画面幅が768px以下の時、表示される画像幅を96vwに指定しています。レスポンシブデザインモードで画面幅を768px以下にしてみて下さい。<div id="container">
の要素に、width: 96%;
がありますので、それを記述しています。
sizes
属性値の2行目の(max-width: 1041px) 65.28vw
ですが、これは、画面幅が769~1041pxの時、表示する画像幅を65.28vwに指定しています。レスポンシブデザインモードで画面幅を769px以上にすると、コンテンツ領域が2カラムになると思いますが、この時、左側のカラムである<div id="main">
の要素に、width: 68%;
がありますので、先述の<div id="container">
のwidth: 96%;
と掛け合わせる事で、65.28vw
という値を計算して出しています。
sizes
属性値の3行目の680px
についてですが、これは、画像幅が1042px以上の時、表示する画像幅を680px固定にしています。
そして、srcset
属性の値についてですが、こちらは画面幅の画像幅の仕様から、4パターンの画像をサーバに登録しています。これによって、ブラウザは最適な画像を選び、それだけを読み込みする事になります。
もう少し細かく制御したい場合は、例えば、308wと507wの中間として405wの画像と、502wと680wの中間として591wの画像を登録しておくと良いかなと思います。
ちなみに、ブラウザの『最適な画像を選ぶ仕組み』というのは、ブラウザによって異なります。Firefoxでは、画面幅を変える毎に、適した大きさの画像を読み込みますが、Chromeでは、大きめの画像をキャッシュした場合、小さめの画像は読み込みしません。
src
属性は、srcset
とsizes
属性に非対応なブラウザに対してのフォールバックの画像になります。
alt
属性は画像に対する説明で、可能な限り、記述をお願いします。分かりやすい資料としては、入門者向け alt属性の書き方アドバイスのスライドが参考になると思います。
下の画像は、上記の記述で画像を載せた場合になります。レスポンシブデザインモードで、画面幅を変えてみて、どのように画像が変化するか、確認してみてください。
Retina等を考慮する場合
引き続き、この弊社ブログで画像を載せる(img
タグを書く)場合を考えてみます。今回はRetina等を考慮する場合の書き方になります。
Retinaを始めとするデバイスピクセル比は、2倍からと思われがちですが、世の中には様々なデバイスが多数あり、1.3倍とか1.5倍とか1.7倍というものもあれば、3倍、3.5倍、4倍、6倍もあります。(出典: Wikipedia, 前回記事)
そして、ブラウザのズーム率を拡大縮小する事でもデバイスピクセル比が変わるので、例えば0.9倍とか1.1倍の倍率にも、なりえます。(レスポンシブデザインモードでズームを拡大縮小すると、DPRの値が変化する事が分かると思います)
上記を踏まえ、srcset属性を倍率指定で書いていこうとすると、1倍、1.3倍、…、6倍と書いていかなくてはいけない事になる訳ですが、面倒に感じませんか? しかも、細かい倍率(ズーム率の変更時)の対応が不十分に思います。細かい倍率も含めて書くとなると、非現実的ではないでしょうか?
そこで、倍率ではなく、w
という単位のファイル画像幅を使って書いてみたいと思います。以下の例は、デバイスピクセル比3倍までで、w
で書いた記述例になります。
See the Pen XPKjdZ by sp-sephiroth (@sp-sephiroth) on CodePen.
このような書き方をする事で、ブラウザがsizes
やsrcset
属性の値から、適切なデバイスピクセル比の画像を自動的に選択してくれる事になります。
少し長い記述かもしれませんが、srcset
の登録数が多いものの、分かりやすい記述の部類に思うのですが、どうでしょうか?
なお、ファイル画像幅は、100wから2200wまでで100w(px)刻みになっていますが、本来ならば正確に記述する事が望ましいと思います。例えば、デスクトップで画面幅を320pxにした場合、表示する画像幅は307.2pxで倍率は1倍なのですから、308wの画像があった方がより良いと思います。正確にしてないのは、ちょっと面倒だった為記述の分かりやすさを優先した為です。
今回、100w(px)刻みとしましたが、例えば、20KB刻み等、ファイルサイズで各画像を用意する考え方もあるようです。この場合は、より通信を最適化できそうですが、画像の書き出しには苦労しそうです。WebサービスのResponsive Image Breakpoints Generatorでは、そうした書き出しを自動化しますので、よければ試して下さい。
下の画像は、上記の記述で画像を載せた場合になります。レスポンシブデザインモードで、画面幅を変えたり、DPRを2や3に変えたり、ブラウザのズーム率を変えたりして、どのように画像が変化するか、確認してみてください。
終わりに
今回は、srcset
とsizes
属性を使ったimg
タグの記述について書いてみました。
レスポンシブイメージでは、この他に、アートディレクションと、別の画像形式を読み込ませる方法がありますが、続きはまた後日、ブログの担当がまた周ってきた時に書きたいと思います。