Retina Display – レティナ・ディスプレイ
もう聞き馴れた名称かと思います。

もともとは Apple が開発した高精細ディスプレイで、初めて採用されたのは iPhone 4 のときでした。
レティナ(Retina)とは英語で「網膜」を意味します。
それまで一般的だった解像度の4倍の密度で、肉眼では画素・ピクセルを認識できない水準になっており、文字通り「常識を覆した」素晴らしいディスプレイです。

ウェブサイトを制作するとき、この「Retina Display」に対応することは既に常識となっいるワケですが、その対応方法は様々で、どの解決策にも一長一短があります。

今日ここで紹介する「Retina-Srcset.js」は Retina Display に対応するための1つの解決策。

開発に至った理由とその使い方を説明するために、まずは従来の Retina Display 対応方法を復習してみましょう。

画像のサイズを2倍にする

まずは最も単純な方法です。

例えば、画像の表示サイズが「横120px × 縦80px」の場合、その倍のサイズの「横240px × 縦160px」の画像を用意して<img>タグで埋め込みます。

<img src="/images/sample-240x160.png" alt="サンプル画像" width="120" height="80">

このとき、表示させるサイズは縦横それぞれ「120px」と「80px」になるので、「width」と「height」の値は当然「120」「80」と指定します。

簡単ですが、レティナ・ディスプレイ以外のデバイスでも2倍のサイズの画像を使うことになるので読み込み速度の遅延に影響します。

スタイルシート(CSS)で Retina Display に対応する

続いてはスタイルシート側で Retina Display に対応する方法です。

具体的には「background-image」で画像を読み込むときに、Retina Display 専用の画像を使い、CSS3から導入された「background-size」でサイズを指定することになります。

単純なコードで書くと次のようになりますね。

.sample {
	width:120px;
	height:80px;
	background-image:url("sample.png");
	-webkit-background-size:120px 80px;
	-moz-background-size:120px 80px;
	-ms-background-size:120px 80px;
	-o-background-size:120px 80px;
	background-size:120px 80px;
}

本来はここで「min-resolution」または「min-device-pixel-ratio」でレティナ・ディスプレイか否かを分岐させますが、基本的には、スタイルシートでの Retina Display の対応はこの方法が最善です。

JavaScript で Retina Display に対応する

JavaScript または jQuery で対応する方法です。
最近注目されている「Retina.js」が最も有名かと思います。

Retina.js

この jQuery ライブラリ[retina.js]では、HTML の中から埋め込まれている <img> タグのsrc属性を調べ、もし Retina Display に対応している画像(ファイルの末尾に「@2x」が付与されているもの)が存在する場合はそれに置き換える、という処理を行います。

例えば「sample.png」という画像を使っている場合、同じフォルダ内に「sample@2x.png」という画像を用意しておくと、「Retina.js」が <img>タグを書き換えて「@2x」の画像を表示させてくれます。

これは非常に便利なのですが、すべての<img>タグを参照するので動作が重くなり、また「@2x」の画像が用意されていない場合はサーバー側で404エラーが発生してしまうことが気がかりです。

HTML5の「srcset」を使う

HTML5から使用可能になった「srcset」はかなり便利な仕様で、画像を Retina Display に対応させることはもちろん、ウィンドウサイズに合わせて画像を切り替えることも可能になります。

具体的には以下のようなコードで実装します。

<img src="sample.png" width="120" height="80" srcset="sample@2x.png 2x">

ここで記述している srcset="sample@2x.png 2x" の「2x」は、「デバイスピクセル比が2倍のとき」を意味しています。

つまり通常は「sample.png」を表示させて、Retina Display のときは「sample@2x.png」を表示させるようになります。

この「srcset」の魅力は、前述の「Retina.js」とほぼ同じように機能し、対応していないブラウザは必要ない画像をダウンロードしないという点です。
ただしデメリットもあり、1つ1つの画像に「srcset」の中身を記述しなければならないので大変面倒になります。

開発した[Retina-Srcset.js]について

Retina Display に対応するために「Retina.js」と「srcset」は非常に魅力的な解決策でした。

しかし、先に挙げたように読み込み速度の遅延や404エラー発生の原因なること、また<img>タグ1つ1つに処理を書き加えねばならないことは大きなデメリットです。

この問題を解決するために開発したのが[Retina-Srcset.js]です。

[Retina-Srcset.js]は <img> タグにクラス名「class=”retina”」を指定すると機能します。

もし画像に「class=”retina”」と記述してあった場合、[Retina-Srcset.js]は <img> タグの中身に「srcset」を書き加え、レティナ・ディスプレイ用の「@2x」という文字列を付与した画像が表示されるようになります。

<img src="./images/sample.png" width="120" height="80" class="retina">

例えば上記のように「class=”retina”」を付与した画像があると、[Retina-Srcset.js]によって以下のように自動で<img>タグに「srcset」が追加されます。

<img src="./images/sample.png" width="120" height="80" class="retina" srcset="./images/sample@2x.png 2x">

通常表示する「sample.png」と倍の解像度の「sample@2x.png」という画像を2つ用意しておき、対応させたい画像に「class=”retina”」を書き加えるだけなので簡単です。

ライブラリ[Retina-Srcset.js]の導入

コード自体は非常に短く簡潔です。

以下のコードをコピペするだけで使えます。

$(function(){
	var retinaCheck = window.devicePixelRatio;
	if(retinaCheck >= 2) { // Retinaディスプレイのときを分岐させている
		$('img.retina').each( function() {
			var retinaimg = $(this).attr('src').replace(/\.(?=(?:png|jpg|jpeg)$)/i, '@2x.');
			$(this).attr('srcset', retinaimg + " 2x");
		});
	}
});

著作権は放棄していませんが、無料ですし、誰でもご自由にお使いいただいて結構です。

使ってみた感想はもちろん、改善点があればぜひお知らせください。