画像のRetinaディスプレイ対応
高解像度のディスプレイで画像を表示すると、ぼやけることがあります。
本ページでは、画像をRetinaディスプレイ対応する方法を説明します。
高解像度のディスプレイでの画像表示
iPhoneは、Retinaディスプレイが使われているため、小さなディスプレイでも高解像度です。また、Androidでも高解像度ディスプレイが多く採用されています。
高解像度にもかかわらず、画像を表示するとぼやけることがあります。
上記の2つの文字は、スマートフォンで表示した画像です。左の「あ」の文字は、普通に表示しています。右の「あ」の文字は、高解像度ディスプレイに対応した画像を表示しています。左の文字の方が、ぼやけているのがわかると思います。
ぼやける原因
ぼやける原因は、画像の縦横をCSSピクセルで決めているためです。
「ビューポートの説明と設定」で説明したとおり、高解像度ディスプレイは横幅を本来表示できる能力ではなく、414pxなどと認識しています。このため、文字も大きく表示されますが、画像もCSSピクセルに合わせて拡大されています。
以下のように、1pxごとに格子がある画像を作ったとします。
これを、高解像度ディスプレイで表示して、1pxごとに格子を付けると、以下のようになります。
9px × 9pxだった画像が、27px × 27pxに拡大されて、白黒だった格子は灰色などで埋め合わせられています。これが、ぼやける原因です。
スマートフォンは、CSSピクセルで絵画するため、9px × 9pxの画像をデバイスピクセル換算にして、27px × 27pxで表示しています。
今回は、9pxが27pxと縦横3倍に拡大された例ですが、この比率(デバイスピクセル比と言います)は機種によって1.5倍や2倍など、さまざまです。
対策
最後には27px × 27pxで表示されるため、最初から27px × 27pxの画像を使い、CSSでは9px × 9pxで指定します。使う画像は以下です。
先ほどは1px × 1px毎でしたが、上の図では3px × 3pxを1マスにして白黒の格子にしています。
HTMLでは、以下のように9px × 9px(CSSピクセル)で表示するようにします。
<img src="images/image1.png" alt="" style="width:9px;height:9px;">
これをスマートフォンで表示して、1pxごとの格子を付けると、以下のようになります。
灰色などで埋め合わせられるのではなく、元々の画像で表示されているのが確認できます。つまり、縦横3倍の画像を使えば、デバイスピクセルに画像の1pxを対応させて表示できるため、ぼやけないという訳です。
対策の効果
対策の効果の確認です。16pxの文字をそのまま画像にして表示したものと、48pxの文字で作成した画像を1/3にして表示したもので比較してみます。以下は、スマートフォンのスクリーンショットです。
- 16pxの文字をそのまま画像にして表示
- 48pxの文字で作成した画像を1/3にして表示
画像を大きく作って縮小した方(下の方)が、綺麗に見えると思います。
srcset属性
縦横3倍の画像を用意したとします。この場合、デバイスピクセル比が1.5倍や2倍の機種は、画像を縮小して表示する必要があります。
この対応として、デバイスピクセル比に応じて、表示する画像を切り替えることもできます。以下は、HTMLの例です。
<img class="test" srcset="images/image-300w.png, images/image-450w.png 1.5x, images/image-600w.png 2x, images/image-900w.png 3x" src="image-900w.png" alt="画像の説明">
赤字部分は、画像の横幅がわかるように名前を付けています。例えば、300wであれば300pxです。各サイズで、ぼやけていない画像を準備する必要があります。青字部分は、デバイスピクセル比です。
デバイスピクセル比が1倍であればimage-300w.png、1.5倍であればimage-450w.png、2倍であればimage-600w.png、3倍であればimage-900w.pngが表示されます。最後の属性srcで指定した画像は、srcsetに対応していないブラウザの時に表示されます。
CSSでは、以下のようにクラスtestの幅を300pxに指定します。
.test { width: 300px; }
これで、どの画像が使われてもCSSピクセルとして300pxの横幅で表示されます。横幅は300pxですが、デバイスピクセル比に応じて大きな画像が使われるため、ぼやけずに表示ができます。
sizes属性
先の例では、パソコンなどの大きなディスプレイでも、300pxで表示されます。大きなディスプレイの時は、大きなサイズで画像を表示したい場合、sizes属性が使えます。以下は、例です。
<img srcset="images/image-300w.png 300w, images/image-450w.png 450w, images/image-600w.png 600w, images/image-900w.png 900w" sizes="(max-width: 899px) 300px, 900px" src="images/image-900w.png" alt="画像の説明">
赤字部分は、画像の横幅(px)をw幅記述子で示します。青字部分は、メディアクエリです。上の例では、899px以下、それ以上で条件分けしています。緑字部分は、表示する横幅です。メディアクエリの条件によって300px、900pxで表示するようにしています。
このため、ビューポートが899px以下であれば横幅300pxのimage-300w.png、900px以上であれば横幅900pxのimage-900w.pngが表示されます。
ただし、これはデバイスピクセル比が1の時です。デバイスピクセル比が1.5、2や3の時は、1.5倍(450w)、2倍(600w)や3倍(900w)の画像が使われて、sizesで指定したCSSピクセルの横幅で表示されます。
つまり、スマートフォンではデバイスピクセル比に応じた画像が使われて、横幅300px(CSSピクセル)で表示されます。パソコンでは、900pxの画像が横幅900pxで表示されます。
次のページ「表のレスポンシブ対応」