Webサイト&WebアプリのRetina対応方法まとめ このエントリをはてなブックマークに登録

2013年01月28日

takurutakuru / , , , ,

こんにちは。
会社からMacBookPro Retinaディスプレイモデルを支給されました浅海です。

Retinaディスプレイ、非常に快適なのですが、Retinaディスプレイに最適化されていないWebページやアプリケーションでは、ビクセルベースで作られている部分がすこしぼけたように見えてしまいます。
特に文字を画像にしている場合なんかは、かなり気になります。

Retinaディスプレイは既にiPhoneで使われているほか、一部のAndroidもRetina相当の解像度を持っているモデルが登場しており、モバイルWebサイトやWebアプリがRetinaディスプレイを意識した作りになっていることはよく見られるようになりました。
これからもPCなど、Retinaディスプレイ対応のニーズは増えるだろうと思い、対応方法をまとめました。

目次

  1. imgタグ
  2. CSS
  3. JavaScript
  4. Google Maps
  5. canvasタグ
  6. サンプル

imgタグ

Retinaディスプレイで見た時に、webサイトの画像がボケて滲んだように見えてしまうという現象があります。
これを回避するには、imgタグに解像度を2倍にした画像を使い、widthとheight属性には画面上に表示する大きさを指定する方法があります。

たとえば、以下のような125x125のtest.pngという画像があるとします。

[cc lang="html"]

[/cc]

このままではRetinaディスプレイで見たときにボケボケなってしまうので、これを回避するために縦横2倍の大きさ(250x250)の画像を用意します。
それを仮にtest@2x.pngとして保存し、imgタグを以下の様に書き換えます。
@2xというのは高解像度画像に使うサフィックスの慣例です。特に厳密なルールがあるわけではないので、どんな名前でも大丈夫です。

[cc lang="html"]

[/cc]

高解像度版の画像サイズは250x250ですが、widthとheight属性にはもともとの大きさである125x125を指定しています。
このようにすれば、Retinaディスプレイの謎技術により、表示上の125x125の領域に250x250の画像を表示してくれます。

下に比較画像を載せました。
Retinaディスプレイでのスクリーンキャプチャなので、ピクセル数が表示上の2倍になっています。
Retinaディスプレイで125x125の画像を倍に引き伸ばす時にどれだけ画像が劣化しているのかよく分かると思います。

この方法を使った場合、非Retinaディスプレイで見ると、ブラウザが250x250の画像を125x125に縮小して表示することになります。
表示が酷く崩れることは無いかとは思いますが、画像によってはジャギーなどが入ってしまう可能性があります。
そのような場合には、次に紹介しているCSSでの画像切り替えを使うと良いでしょう。

CSS

画像をHTML要素のbackground-imageとしてCSSで指定している場合は、画像の切替をCSSですることができます。

Media Query

CSSのメディアクエリを利用する方法です。

bodyの背景として、100x100のtest.pngという画像を設定する場合、通常は

[cc lang="css"]
body{
background-image: url("test.png");
}
[/cc]

のようにしますが、Retina対応をする場合は、

  1. background-sizeで通常の画像サイズを指定する
  2. メディアクエリのmin-device-pixel-ratioかmin-resolutionでRetinaディスプレイを判別

の手順を踏む必要があります。
具体的には以下のようになります。

[cc lang="css"]
body{
background-image: url("test.png");
background-size: 100px 100px;
}
@media screen and (-webkit-min-device-pixel-ratio:2),
(min-resolution: 2dppx){
body{
background-image: url("test@2x.png");
}
}
[/cc]

min-device-pixel-ratioは、w3cの仕様に無いwebkitの独自拡張です。
標準化が進んでいるのはmin-resolutionの方ですが、webkitがmin-resolutionに対応していないので、webkitだけmin-device-pixel-ratioを使用しています。

min-resolutionで指定しているdppxとは、dot per pixelを表す単位です。
2 dot per pixelなのでRetinaディスプレイが該当するわけです。
この部分の単位には、他にもdpcmやdpiなども指定できるようです。

CSS4 image-set

iOSがバージョン6となった時に、safariでimage-setが使えるようになりました。
そのため、CSS4を先取りし、image-setを使ってRetinaディスプレイに対応するという手もあります。

[cc lang="css"]
img#main{
background-image: image-set(url("test.png") 1x, url("test@2x.png") 2x);
}
[/cc]

このように書くことにより、1xの時の画像、2xの時の画像、というように出し分けることができます。
まだベンダプレフィックスが必要なプロパティなので注意してください。

javascript

javascriptで動的に出し分けるライブラリがあるので紹介します。

retina.js

http://retinajs.com/

bodyの最後でretina.jsを読み込んでおけば、クライアントがRetinaディスプレイだった場合に、勝手にサーバから@2xのプレフィックスを付けた画像をロードしてくれます。

Google Maps

Google Maps自体はRetina対応されているのですが、Google Mapsのマーカーにオリジナルの画像を使うと、Retinaディスプレイではボケて表示されてしまいます。
WebアプリでGoogle Mapsを使う場合などは重要になってくるテクニックです。

通常、オリジナルマーカは以下の様に作成します。

[cc lang="javascript"]
var marker_image = new google.maps.MarkerImage('test.png');

new google.maps.Marker({map: map, icon: marker_image});
[/cc]

Retinaディスプレイに対応するには高解像度の画像を使えば良いように思えますが、それだけではRetinaディスプレイで見た時にぼけたままです。
MarkerImageのscaledSizeに、表示上のサイズを指定する必要があります。

[cc lang="javascript"]
var marker_image = new google.maps.MarkerImage('test@2x.png');
marker_image.scaledSize = new google.maps.Size(24, 24);

new google.maps.Marker({map: map, icon: marker_image});
[/cc]

通常の画像サイズが24x24pxとしていますので、test@2x.pngは48x48pxの画像です。

実際の比較画像を載せます。
左がRetina非対応のマーカー、右がRetina対応をしたマーカーです。

使用アイコン http://www.icons-land.com/

html5 canvas

canvasに描画している内容もピクセルベースなので、ただ単に描画しただけでは、Retinaディスプレイで見た時に描画内容がボケてしまいます。
これを解消するために、CSSで実際のサイズを指定し、canvasタグのwidthとheightでは高解像度(2倍)のサイズを指定する必要があります。

[cc lang="css"]
canvas{
width: 150px;
height: 150px;
}
[/cc]

[cc lang="html"]

[/cc]

このようにした場合、注意点があります。
ブラウザでの表示上のサイズは変わりませんが、内部では2倍のcanvasに描画しているものを50%に縮めて表示しているわけです。
そのため、座標や線の太さなどは、全て既存の2倍にして描画する必要があります。
全て2倍を指定して描画するか、context.scaleを2にして描画してください。

canvasの手書きライブラリを使用して比較してみました。
左がRetina非対応、右がRetina対応版です。
全く同じ絵を描いているわけではありませんが、左に描いた絵の不鮮明さはわかると思います。

サンプル

記事中にスクリーンキャプチャとして紹介したもののHTMLを実際に用意しました。

http://hai3.net/dev/retina.html

Retinaディスプレイで見ればその違いがわかりますし、非Retinaディスプレイで見た場合には、Retina対応による差異はそんなにないことが確認できると思います。

  1. メモからはじめる情報共有 DocBase 無料トライアルを開始
  2. DocBase 資料をダウンロード

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント


we use!!Ruby on RailsAmazon Web Services

このページの先頭へ