レスポンシブイメージとは何か
“レスポンシブイメージ”と画像の大きさ
レスポンシブウェブデザインでは大きなディスプレイを持つデスクトップデバイスとそれに比べて小さなディスプレイを持つモバイルデバイスの両方に対応する必要があります。
例えば1920x1080の表示領域があるデスクトップデバイスと320x480の表示領域があるモバイルデバイスがある時にデスクトップデバイスで横幅いっぱいに表示されるように用意した大きな画像をモバイルデバイスで表示するときれいに表示されないだけでなく、通信容量の無駄になってしまいます。小さい画像や中間の大きさの画像を用意する方法もありますが、小さな画像をデスクトップデバイスで拡大して表示してもきれいに表示することができません。
レスポンシブイメージではデスクトップデバイス用には大きな画像を、モバイルデバイス用には小さな画像をというように適切な画像を選択して表示するようにします。
“レスポンシブイメージ”と画像の解像度
“解像度”と“ピクセル”の話
一言に“解像度”と言いますが、“解像度”という言葉には2種類の意味があります。
- 画素の密度
- 本来の“解像度”の意味で“ppi(pixel per inch)”や“dpi(dot per inch)”の単位で表され、1インチ(2.54cm)の中にある画素(ピクセル)の数を表します。1インチ四方の正方形で一辺が10ピクセルの場合、解像度は10ppiです。“ピクセル密度”や“画素密度”とも呼ばれます。
- ディスプレイや画像等の大きさ
- “px(pixel、ピクセル)”の単位で表されます。1pxは単純に並んだ画素(ピクセル)の数で長さを表し、解像度は“横幅の画素の数x高さの画素の数(例えば1920x1080など)”の形で表します。画素の大きさはディスプレイによって違うので物理的な大きさが同じでも解像度が同じとは限りません。
“ppi”や“dpi”で表す“解像度”は印刷の分野だったり、ディスプレイの性能を表すために使用されことが多く、ウェブデザインで“解像度”は多くの場合は後者のことを指します。
前述の“画素(ピクセル)”についてですが、一般的にウェブ上で使用される画像の多くはビットマップ画像と呼ばれるもので、色を持った点が並んで画像を表現しています。この点の一つ一つが“画素(ピクセル)”です。画素の数が多いほど精細な画像になります。
また、画像を表示するディスプレイも小さな点を縦横に並べて画像を表現していますが、その点の一つ一つも“画素(ピクセル)”と呼ばれます。
ウェブデザインでは文字やボックス、画像などの大きさを指定するために長さの単位として“px(pixel、ピクセル)”が多く使用されます。これは並んだ画素の数を数える単位で、従来のディスプレイでは1pxの長さは画素1個分と同じになります。
しかし、画素の数が多いほど精細な画像を表示できるのでスマートフォンなどの最新のデバイスに搭載されたディスプレイは画素の一つ一つを小さくして、大きさが同じでも解像度を高めたものになっています。ここで問題になるのが、これまでのように1pxを画素1個で表現すると高解像度のディスプレイではとても小さくなってしまうということです。これを解決するために“CSSピクセル”と呼ばれる単位が設定されています。
CSSピクセルはディスプレイの解像度が異なっても表示される大きさがある程度同じになるように設定されている擬似的な長さです。CSSピクセルに対してディスプレイの実際の画素の数は“デバイスピクセル”と呼ばれますが、高解像度のディスプレイでは1CSSピクセルは複数のデバイスピクセルに跨って表示されます。
1CSSピクセルが何デバイスピクセルで表現されるかを“デバイスピクセル比(device pixel ratio)”で表します。例えば、1CSSピクセルの長さが2デバイスピクセルに表示されるデバイスのデバイスピクセル比は2です。デバイスピクセル比はデバイスごとに決まっています。
ウェブデザインでは長さの単位として“px(ピクセル)”を使用するということは前述しましたが、ほとんどの場合この“px”は“CSSピクセル”のことを指します。
高解像度なディスプレイにきれいに画像を表示するには?
レスポンシブウェブデザインではデバイスピクセル比が低いデバイスとデバイスピクセル比が高いデバイスの両方に対応する必要があります。
従来は、例えば横幅1920CSSピクセルのウェブページの大きさいっぱいに表示したい画像は横幅1920pxのものを用意すれば良かったのですが、これをデバイスピクセル比が高いディスプレイに表示した場合には画像の1ピクセルが複数のデバイスピクセルを使って表示されるため、ぼやけた感じになりきれいに表示されません。デバイスピクセル比が2のディスプレイを最大限活用して画像をきれいに表示するためには表示したいCSSピクセルの2倍の解像度の画像を用意する必要があります。
最新のスマートフォンではデバイスピクセル比が3や4のものも登場していますが、これらのディスプレイを最大限活用するには解像度が3倍や4倍の画像を用意する必要があるということになります。しかし、解像度が4倍の画像をデバイスピクセル比が1のデバイスに読み込ませるのは通信容量の無駄になってしまいます。
レスポンシブイメージではデバイスピクセル比が1のデバイスには解像度が等倍の画像を、デバイスピクセル比が2のデバイスには解像度が2倍の画像をというように適切な画像を選択して表示するようにします。
“レスポンシブイメージ”とアートディレクション
“アートディレクション”とはユーザーの閲覧環境に応じて内容が異なる画像が表示されるようにすることです。“内容が異なる”と言ってもまったく違う画像というわけではなく、同じ画像をクロップ(切り抜くこと)したり、縦横比を変更した画像のことです。
例えば、デスクトップデバイスのように大きくて横幅が広いディスプレイに表示されることを想定した画像をモバイルデバイスのように小さくて横幅が狭いディスプレイにそのまま表示すると縮小されて画像の主題が小さくてわかりにくくなってしまうことがあります。クロップした画像を表示させることでモバイルデバイスでも画像の主題をわかりやすく見せることができます。
レスポンシブイメージではデスクトップデバイス用には大きな画像を、モバイルデバイス用にはクロップした画像をというように適切な画像を選択して表示するようにします。
レスポンシブイメージの埋め込み方法
新しい“レスポンシブイメージ”
HTML5.1から新しく追加された“レスポンシブイメージ”ではHTMLのみでユーザーの閲覧環境に応じて画像を出し分けられるようになります。以下の新しい要素や属性を使用してレスポンシブイメージを埋め込むことができます。
どちらの場合もユーザーの閲覧環境に応じた複数の画像ファイルを指定しても、条件に沿った画像ファイルだけを読み込み、不要な画像ファイルを読み込みません。
レスポンシブイメージを埋め込むこれらの要素で機能も似ていますが、どちらでも良いというわけではなくそれぞれメリットとデメリットがあるので使い分ける必要があります。
“img”要素と“srcset”属性、“sizes”属性
““srcset”属性”とは?
“img”要素に指定される“srcset”属性は表示できる画像ファイルの候補とそれぞれを表示する条件を提示します。ここで重要なのが、“srcset”属性で提示された画像ファイルは“候補”であって指定された条件でその画像ファイルを実際に表示するかどうかはブラウザに任されるということです。想定した通りの画像が表示されない場合があります。なので“srcset”属性は内容は同じで大きさ、解像度が異なる画像をレスポンシブイメージとして埋め込むのに適していますが、画像の内容が変わるアートディレクションには適していません。
“img”要素でのレスポンシブイメージの埋め込み方法は2通りあり、“srcset”属性で画素密度記述子(“x”)を使用する方法と、“srcset”属性で幅記述子(“w”)を使用する方法があります。
“srcset”属性はHTML5.1で新しく追加された属性のためユーザーの環境によっては対応していない場合がありますが、その場合は“src”属性によって示された画像が表示されます。
デバイスピクセル比で読み込みたい画像を指定
“srcset”属性に画素密度記述子を使用した場合、ブラウザが提示された画像の中からデバイスのデバイスピクセル比に応じて最適な画像を選択します。
<img srcset="sample-320.png 1x, sample-640.png 2x, sample-1280.png 3x" src="sample-640.png" alt="サンプル画像">
“srcset”属性に画素密度記述子を使用して埋め込まれた画像は画素密度記述子が“1x”つまりデバイスピクセル比が1のディスプレイで表示することを想定した画像は画像の1ピクセルが1CSSピクセルに、“2x”つまりデバイスピクセル比が2のディスプレイで表示することを想定した画像は画像の2ピクセルが1CSSピクセルを使って表示されます。なので“2x”をつけられた画像ファイルは表示されるとき画像の実際のピクセル数の2分の1のCSSピクセル数で表示されます。これは“3x”や“4x”の場合も同様です。
上の例ではデバイスピクセルが1のデバイスでは“sample-320.png”、デバイスピクセルが2のデバイスでは“sample-640.png”、デバイスピクセルが3のデバイスでは“sample-1280.png”を表示することをブラウザに提案します。
ビューポートの横幅で読み込みたい画像を指定
“srcset”属性に幅記述子を使用した場合、ブラウザが提示された画像の中からビューポートの横幅に応じて最適な画像を選択します。
<img srcset="sample-320.png 320w, sample-640.png 640w, sample-1280.png 1280w" sizes="50vw" src="sample-640.png" alt="サンプル画像">
幅記述子で示す数値は画像ファイルの横幅の実際のピクセル数です。
“srcset”属性に幅記述子を使用して埋め込まれた画像はビューポートの横幅と同じ横幅で表示されます。上の例では画像が横幅320px以下で表示される(=ビューポートの横幅が320px以下)時は“sample-320.png”、320px以上で640px以下で表示される時は“sample-640.png”、640px以上の時は“sample-1280.png”を表示することをブラウザに提案します。
ただし、これはデバイスピクセル比が1の場合で、幅記述子を使用した場合はブラウザがデバイスピクセル比も合わせて計算するので、デバイスピクセル比が異なるデバイスでは指定した通りにならない場合もあります。
“sizes”属性
“srcset”属性で幅記述子を使用する場合“sizes”属性を指定しなければなりません。
“sizes”属性では画像の横幅の表示サイズを指定します。横幅の長さはCSSで定義されている長さの単位を使用します。“calc()”関数が使用できますが、“%”値は使用できません。
<img srcset="sample-320.png 320w, sample-640.png 640w, sample-1280.png 1280w" sizes="50vw" src="sample-640.png" alt="サンプル画像">
上の例では画像の表示サイズは横幅がビューポートの横幅の50%(“50vw”)になります。表示される画像は“sizes”属性で指定された表示サイズをもとに“srcset”属性で示された画像の中から選ばれます。
“sizes”属性ではメディアクエリを使用して条件ごとの画像の表示サイズを指定することもできます。
<img srcset="sample-320.png 320w, sample-640.png 640w, sample-1280.png 1280w" sizes="(max-width: 640px) 190px, 50vw" src="sample-640.png" alt="サンプル画像">
上の例では画像の表示サイズは横幅がビューポートの横幅が640px以下(“(max-width: 640px)”)の場合は190px、そうでない場合は390pxになります。表示される画像は“sizes”属性で指定された表示サイズをもとに“srcset”属性で示された画像の中から選ばれます。
もしビューポートの横幅が1024pxのブラウザで上の例を開いた場合、1024pxは“(max-width: 640px)”ではないので画像の表示サイズは“50vw(=512px)”になります。512pxで表示するのに適した画像は幅記述子が“640w”の画像なので“sample-640.png”を表示することをブラウザに提案します。
ただし、これもデバイスピクセル比が1の場合で、デバイスピクセル比が異なるデバイスでは指定した通りにならない場合もあります。
“srcset”属性が指定されていない場合や、“srcset”属性で画素密度記述子を使用している場合は“sizes”属性指定できません。
“picture”要素
““picture”要素”とは?
“picture”要素も“img”要素と“srcset”属性のように表示できる画像ファイルとそれぞれを表示する条件を提示しますが、“picture”要素の場合はブラウザに選択の余地を与えません。提示された画像は指定された条件通りに選択されるので、“picture”要素は画像の内容が変わるアートディレクションに適しています。
“picture”要素はHTML5.1で新しく追加された新しい要素のためユーザーの環境によっては対応していない場合がありますが、その場合は“picture”要素の中に配置された“img”要素によって示された画像が表示されます。
“picture”要素でレスポンシブイメージを埋め込む
“picture”要素ではその中に配置された“source”要素に指定した“media”属性によって示された条件によって表示したい画像が選択されます。
ブラウザは“source”要素を記述された順番に参照していき、当てはまるメディアクエリを値に持つ“media”属性が指定された“source”要素が見つかればその“source”要素が示す画像を表示し、それ以降の“source”要素は無視されます。当てはまるものがない場合は最後に配置された“img”要素によって示された画像が表示されます。
<picture>
<source media="(max-width: 320px)" srcset="sample-320-sp.png">
<source media="(max-width: 640px)" srcset="sample-640.png">
<source media="(min-width: 640px)" srcset="sample-1280.png">
<img src="sample-640.png" alt="サンプル画像">
</picture>
上の例ではビューポートの横幅が320px以下の時は“sample-320.png”、320px以上で640px以下の時は“sample-640.png”、640px以上の時は“sample-1280.png”を表示します。
画像の表示サイズはCSSなどで特に指定されていなければそれぞれの画像の実際のピクセル数と同じCSSピクセル数で表示されます。
“picture”要素でもその子要素となる“source”要素に複数の画像ファイルを提示した“srcset”属性や“sizes”属性を指定することができます。これらを掛け合わせて複雑な条件で画像を出し分けることも可能です。
<picture>
<source media="(max-width: 320px)" srcset="photo-sp-1.jpg 1x, photo-sp-2.jpg 2x">
<source media="(max-width: 640px)" srcset="photo-tb-1.jpg 1x, photo-tb-2.jpg 2x">
<source media="(min-width: 640px)" srcset="photo-pc-1.jpg 1x, photo-pc-2.jpg 2x">
<img src="photo-pc-2.jpg" alt="サンプルの写真">
</picture>
複数の形式の画像を提示する
“picture”要素では“source”要素に指定した“type”属性によって一部のブラウザが対応していないと想定される形式の画像を埋め込む時に複数の形式の画像ファイルを提示することができます。
ブラウザは“type”属性によって示されたMIMEタイプに応じて表示する画像を選択し、示された形式に対応していない場合はその“source”要素は無視されます。
<picture>
<source srcset="sample-image.svg" type="image/svg+xml">
<source srcset="sample-image.webp" type="image/webp">
<img src="sample-image.png" alt="サンプル画像">
</picture>
上の例ではブラウザがSVG形式に対応していれば“sample-image.svg”、そうでなければWebP形式の“sample-image.webp”、WebP形式にも対応していなければ“img”要素で示された“sample-image.png”が表示されます。