TORTERECETTE

猫分儀スミレの開発日記 跡地

Retina時代のWeb制作

すっごい古い記事です ご注意下さい


Retinaディスプレイを搭載したiPhone 4が発売されて一年半。
巷では高解像度のiPadやMacBookの発売が噂され、Mac OS XではiPhoneのRetinaディスプレイに相当するHiDPIモードがほぼ完成に近付いています。

これら高解像度ディスプレイを搭載した環境では、互換性を維持するため、低解像度の環境に合わせて作られたコンテンツは基本的に低解像度のまま表示されます。

それはウェブブラウザにおいても例外ではありません。従来のウェブページは何の問題も無く表示されますが、新しい高解像度のデバイスには、新しい高解像度のコンテンツを提供したいものです。

Retinaディスプレイを搭載したiPad、そしてパソコンが普及した時、ウェブ制作の手法も変化を求められます。来るべき時代に備え、今のうちにRetinaディスプレイへの対応方法を確認しておきましょう。

※ 以下に記した手法はMacおよびiOSのSafariで動作確認を行っていますが、
これらの手法が将来もずっと利用できるという保証はありません。
マイクロソフトが余計なことをして全て台無しになるという可能性にご留意下さい。(笑)




CSSで出来ることはCSSでやる
CSS3対応ブラウザの普及で、角丸、グラデーション、ドロップシャドウなど、従来は画像が必要だったデザインも、CSSだけで表現する事が可能になってきました。

CSSを使った角丸(border-radius)、グラデーション(background:linear-gradient等)、ドロップシャドウ(box-shadow)は基本的に全て解像度非依存なので、これらを使用しておけばRetinaディスプレイへの対応はノープロブレムです。


画像はTumblrでの例。

画像を使った角丸とborder-radiusを使った角丸が混在していますが、後者は高解像度になっても美しい丸みが維持されています。また、box-shadowなどで表現されたボタンのハイライトなどもジャギーが発生していませんね。

画像を使用しつつ高解像度に対応する方法もありますが(後述)、そっちは結構面倒なので、なるべくCSSで出来る事はCSSでやった方がいいです。



ベクター画像(SVG等)を使う

画像はapple.comでの例。
メニューのリンゴマークやテキストなどにSVG画像が使われています。
SVGなどのベクター画像は当然解像度非依存ですので、Retinaディスプレイにも容易に対応できます。



テキストを使う(5/13修正)

通常のテキストは全て解像度非依存です。フォントは一種のベクター画像のようなものです。何もしなくても、常に最適な解像度でレンダリングされるでしょう。
text-shadow、Webフォントなどを駆使すれば、いわゆる文字画像を使わなくても、かなり複雑な表現を行うことが出来ます。



背景画像を使う場合、二種類の解像度を用意する
.icon{
    background-image:  url(32x32.png);
    background-size:   32px 32px;
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
    .icon{
        background-image:  url(64x64.png);
    }
}
あらかじめ「background-size」で背景画像の大きさを固定しておき、Media Queryの「min-device-pixel-ratio」条件分岐でRetina環境のみ高解像度の画像を読み込むように設定します。
※ device-pixel-ratioの概念については後述。

上記のような書き方をしておけば、従来の通常解像度のパソコンや、CSS3に未対応の古いブラウザを使用している場合、「32x32.png」の方の画像が使用されます。
互換性もバッチリ!
※ 現在はWebKit系のブラウザしか対応していないため、上記の例では「-webkit-min-device-pixel-ratio」と記述していますが、将来的には「min-device-pixel-ratio」といった記述が通用するようになるでしょう。

いわゆる「CSSスプライト」を使用している場合、Retina環境への対応は画像の差し替えと「background-size」の設定だけでOKです。
「background-position」の値を変える必要はありません。
※ 将来的にはimage-setによって、より簡単に記述出来るようになるかもしれません。後述。


画像は当サイトの例。
メニュー部分に二種類の解像度のCSSスプライトが用意されています。


画像はTwitterのツイートボタン。鳥のアイコン部分が背景画像になっていて、二種類の解像度のCSSスプライトが用意されています。



そもそもdevice-pixel-ratioって何よ?
Retinaディスプレイでのウェブページの表示は、互換性の維持のため、CSSにおける「1px」がディスプレイ上の「2ピクセル」として扱われます。

CSS単位の「px」と、実際の画面上での「ピクセル」がどれだけ乖離しているか、を表す数値が「device-pixel-ratio」です。

従来の普通のパソコンの「device-pixel-ratio」は全て「1」です。古いiPhoneなども「1」になります。

それに対し、Retinaディスプレイを搭載したiPhone 4は、実際の画面解像度が「640 x 960ピクセル」ですが、CSSから取得出来る仮想的な画面解像度は「320 x 480px」ですので、「device-pixel-ratio」は「2」です。画面がHiDPIモードのMacも「2」になります。

中くらいの解像度のAndroid機では「1.5」などの値が設定されていることが多いようです。

この「device-pixel-ratio」をMedia Queryの条件分岐に用いたのが、先述の…
@media only screen and (-webkit-min-device-pixel-ratio:2){…だったというわけです。

※ iPhoneではviewportの設定によって表示サイズが変動しますが、device-pixel-ratioには影響しません。基本的にdevice-pixel-ratioの値はデバイス毎に固定です。



JavaScriptでdevice-pixel-ratioを取得する
対応したブラウザでは、「window.devicePixelRatio」でdevice-pixel-ratioの値を取得する事が出来ます。
hoge = 1;
if(window.devicePixelRatio){
    hoge = window.devicePixelRatio;
}

if(hoge >= 2){
    alert("Retinaディスプレイ!!");
}else{
    alert("ふつうのディスプレイ。");
}
特殊な例かもしれませんが、JavaScriptでコンテンツを表示しているような場合、この方法で表示する画像を振り分けるなどの対応が可能になるでしょう。

ウェブサーバ側でdevice-pixel-ratioを取得する方法は今のところ無いようです。JavaScriptで取得した値をどうにかしてサーバに送りましょう。



img要素(5/13修正)
<img src="1280x720.png" width="640" height="360" />現在のところ(※)、img要素に二種類以上の解像度の画像を同時に設定する方法はありません。とりあえず大きい画像を指定しておいて、widthとheightに半分の数値を書きましょう。
JavaScript等を使って画像を入れ替えるのもアリです。
※ 将来的にはimage-setによって可能になるかもしれません。後述。



面倒くさい。もっと簡単にならないの?
(5/13追記)上記のように、CSSの背景画像の切り替えは記述する内容が複雑です。しかし将来、CSS4の時代になれば、「image-set」の登場によってより簡単にRetinaディスプレイ対応が可能になるかもしれません。
CSS3
.icon{
    background-image:  url(32x32.png);
    background-size:   32px 32px;
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
    .icon{
        background-image:  url(64x64.png);
    }
}

CSS4(?).icon{
    background:        image-set(url(32x32.png) 1x, url(64x64.png) 2x);
}
「image-set」は提案されたばかりの新しい記述方法で、採用されるかどうかは全く分かりませんが、もし標準化されれば複数の解像度の画像を一括でまとめる事が出来るでしょう。
また、Media Queryではディスプレイの解像度を識別することしか出来ませんが、「image-set」は純粋に画像の解像度に関する情報を付加するものなので、ブラウザが自動的に最適な解像度を選択することが可能になります。iPadなどでページをズームした時に自動的に高解像度の画像を読み込む、といった処理を、ページ制作者が意識しなくても勝手にやってくれるようになるでしょう。
<img src="32x32.png" set="32x32.png 1x, 64x64.png 2x" />また、同様のアルゴリズムをimg要素にも応用することが提案されています。そもそもimg要素は単独ではRetinaディスプレイ対応が不可能でしたが、上記のように互換性を保ったまま複数の解像度の画像を組み込むことが可能になるかもしれません。
※ 上記の方法はあくまで、将来的に実現するかもしれない!という機能です。今のところは実際に利用できるものではありません。



ファビコン(favicon.ico)はマルチサイズ対応にする

通常、いわゆるファビコンでは「16x16」ピクセルの画像が使用されていますが、Retinaディスプレイ環境では「32x32」の画像が使われるようになるでしょう。

Windowsのアイコン形式である「ICO」ファイルは、元々、様々な解像度の画像を一つのファイルに同梱する事が可能な形式です。ファビコンには最低限、「16x16」と「32x32」の二種類の画像を入れておきましょう。

普通のファビコン作成ツールなどでは「16x16」の解像度にしか対応していない場合が多いので要注意。本格的なICOファイル編集ソフトが必要になるでしょう。



Retinaディスプレイは持ってないけど、Retinaディスプレイでの表示を試したい!
MacのHiDPIモード、およびSafariを使用することで擬似的に高解像度表示を再現することが出来ます。HiDPIモードは今のところ隠し機能ですので、自己責任でお願いします。詳しいやり方はぐぐってください。