Web制作メモ -トップへ-

jQueryでimg要素とCSS背景画像をRetina対応する方法

JavaScript2015.04.01 07:45

画像を普通に表示するとRetina(高精細ディスプレイ)ではぼやけて表示されます。

最近は高精細ディスプレイが増えている為、Retina対応の画像処理が必要になってきました。

以下はHTMLのimg要素とCSSのbackgroudで指定した画像を、jQueryでRetina対応する方法です。

縮小して表示するだけだとPageSpeedで減点される

表示するサイズより大きな画像を読み込ませて縮小して表示すれば、Retinaディスプレイでも綺麗に表示できます。

しかし、単純に画像を縮小表示する方法だと、Retina以外のディスプレイでも大きな画像をダウンロードすることになり、Goolge PageSpeedで「画像が最適化されていない」と減点されてしまいます。

PageSpeedの提案

面倒だからと言って、単純に縮小表示で対応してはいけないようです。

img要素の対応方法

img要素はjQueryで大きな画像に置き換える方法で対応します。

javascriptが無効の時に動きませんが、それは諦めるしかありません。

window.devicePixelRatioがRetinaは「2」で他のスマホは「1.5」とか色々ある為、1より大きい場合に画像を置き換えています。

画像はimg要素のwidth/height属性やCSSでサイズを指定した上で、classに「2x」と指定、ファイル名末尾に「@2x」と付けた2倍の大きさの画像ファイルを準備しておく必要があります。

$(function(){
    if(window.devicePixelRatio > 1){
        $(".2x").each(function() {
            $(this).attr("src", $(this).attr("src").replace(/(\.)(png|jpg|gif)/, "@2x$1$2"));
        });
    }
});

CSS背景画像の対応方法

CSSの場合はメディアクエリで分岐する方法もあります。(※参考リンク

ただ今回は、img要素に合わせてjQueryを使って対応します。

メディアクエリを使う方法だと、devicePixelRatioが2のデバイス限定のような気がして(不確か)、devicePixelRatioが1.5のAndroidに対応できない気がしたからです。

また、img要素を対応させた方法と対応方法が違うと、「img要素は対応できているのにCSS背景画像が対応できていない」という状態になると面倒なので、こういう場合は処理する方法を合わせておくのが無難です。

CSSの背景画像もimg要素と同じく表示するサイズを予め指定しておく必要があります。これはbackground-sizeで指定します。

そして、img要素の場合と同様に、背景画像を表示する要素のclassに「2x」と指定、ファイル名末尾に「@2x」と付けた2倍の大きさの画像ファイルを準備しておく必要があります。

$(function(){
    if(window.devicePixelRatio > 1){
        $(".2x").each(function(){
            $(this).css("background-image", $(this).css("background-image").replace(/(\.)(png|jpg|gif)/, "@2x$1$2"));
        });
    }
});

img要素とCSS背景画像の両方に対応

上記2つを合体すると使い勝手が良いです。

クラスに「2x」と指定して「@2x」と末尾についたファイルを作成するだけで、img要素も背景画像もRetina対応できます。

    if(window.devicePixelRatio > 1){
        $(".2x").each(function(){
            if($(this).get(0).tagName=="IMG"){
                $(this).attr("src", $(this).attr("src").replace(/(\.)(png|jpg|gif)/, "@2x$1$2"));
            } else {
                $(this).css("background-image", $(this).css("background-image").replace(/(\.)(png|jpg|gif)/, "@2x$1$2"));
            }
        });
    }

img要素のときはsrcを置き換え、それ以外の場合はbackground-imageを置き換えています。