画像のレスポンシブ化。画面サイズに合わせて読み込む画像を変える方法

2017/06/01

レスポンシブサイトを制作する際に気にしたいのが、画像のレスポンシブ化。

画面サイズやディスプレイの画素密度に合わせて最適な画像だけを読み込むことで、無駄に通信が発生させないようにし、ページの表示速度を上げましょう。

CSSのメディアクエリを使用する場合

画像をimg要素で読み込むのではなく、背景画像として読み込ませます。

背景画像はdiv要素に適用します。
そのdiv要素の縦横比が常に一定に保たれるようにします。
横幅がiPad以上の時は”image-large.jpg”を、以下の時は”image-small.jpg”を読み込むようにします。

デモ (ブラウザサイズを変えてみてください。画像が変わります。)


//example.html
<div class="image"></div>


//style.css
.image {
  width: 100%;
  background-image: url("image-small.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.image:after{
  content: "";
  display: block;
  padding-top:50%; // 縦横比が1:2となる
}
@media screen and (min-width:768px){
  .image {
    background-image: url("image-large.jpg");
  }
}

div要素を常に一定の縦横比に保つために、擬似クラスの:afterを使用しています。

液晶がRatinaかどうかで、さらに分岐させることもできる

上の例では、読み込む画像の判定基準は画面のサイズだけでした。

Ratinaディスプレイのように高精細な液晶の時には高精細な画像を読み込みたい、逆にRatinaではない時には荒い画像で十分というときもあります。

そんな時には画素密度による分岐をCSSに追加しましょう。

デモ (レスポンシブモードで画素密度を変えてみてください。画像が変わります。)


//style.css
@media (-webkit-min-device-pixel-ratio: 2),
       (            min-resolution: 2dppx){
  .image{
    background-image:url("image-small@2x.jpg");
  }
}

@media (-webkit-min-device-pixel-ratio: 2) and (min-width:768px),
       (            min-resolution: 2dppx) and (min-width:768px){
  .image{
    background-image:url("image-large@2x.jpg");
  }
}

メディアクエリはandでつないだときは2つの条件を満たす場合に適用され、, (コンマ)でつないだときはどちらか一方の条件を満たす場合に適用されます。

レスポンシブイメージで実装する場合

html5で追加されたレスポンシブイメージなら、CSSによる設定すら必要ないのでとても楽に実装できます。

picture要素を使います。

デモ ブラウザ幅を変えてみてください。(画像が変わらない場合、ブラウザ幅を変えた際にページを更新してみてください。)


small image

//example.html
<picture>
  <source
    media="(min-width:768px)" 
    srcset="image-large.jpg"
  />
  <img
    src="image-small.jpg"
    alt="small image"
  />
</picture>

picture要素の中、一番最後に必ずimg要素を配置しましょう。
レスポンシブイメージで対応していないブラウザの場合、このimg要素で指定した写真が表示されます。
img要素の後ろにsource要素を配置しても無効になりますので注意しましょう。

source要素は下記の属性を持っています。

Ratinaでの分岐も可能

レスポンシブイメージでもCSS同様にRatinaディスプレイでの分岐ができます。

デモ レスポンシブモードで画素密度を変えてみてください(画像が変わらない場合、ページを更新してみてください)
small image


//example.html
<picture>
  <source
    media="(min-width:768px)" 
    srcset="image-large.jpg,
            image-large@1.5x.jpg 1.5x,
            image-large@2x.jpg 2x"
  />
  <source
    srcset="image-small.jpg,
            image-small@1.5x.jpg 1.5x,
            image-small@2x.jpg 2x"
  />
  <img
    src="image-small.jpg"
    alt="small image"
  />
</picture>

srcsetに複数の画像のパスを指定するときは、画像のパスを,(コンマ)で繋ぎます。
画素密度の指定をするときは、画像のパスの後ろにスペースを挟んで記述します。

ブラウザ側に読み込む画像を判断させる

上のpicture要素を使用した例では、細かく設定ができるので意図通りの画像を読み込めます。
なので、“スマホの時には縦長の画像を、パソコンの時には横長の画像を読み込ませたい”といったことが可能です。

そこまで必要ないとき、例えば単純に“デバイスに合わせて最適なサイズの画像を読み込ませたい”なんてときはもっと楽な方法があります。

この方法ではpicture要素ではなくimg要素を使用します。

デモ ブラウザ幅や画素密度をいじってみてください。(変わらない場合はページを更新してみてください。)


//example.html
<img
  sizes="90vw"
  src="image-small.jpg"
  srcset="image.jpg 320w,
          image@2x.jpg 640w,
          image@3x.jpg 960w,
          image@4x.jpg 1280w"
/>

srcset属性が使えないブラウザのために必ずsrc属性を指定しましょう。

sizes属性に指定した90vwとは、画面幅に対して90%の幅、という意味です。つまり、画像サイズは画面幅の90%です。それに見合った画像を選びなさいという指定です。

srcset属性には、画像のURLとその画像の横幅を指定します。複数の画像を指定する時には、,(コンマ)でつなぎます。

これだけ設定するだけで、ブラウザが画面サイズや画素密度を考慮して最適な画像を選択し読み込みます。

まとめ

レスポンシブなウェブサイトで最適に画像を読み込ませるための方法をご紹介しました。