PCとスマートフォンで画像を切り替える【jQuery連載09】

前回は、ソーシャルボタンをまとめて設置ができるプラグイン「jQuery.socialbutton」を使用しましたが、今回はレスポンシブレイアウトなどで使用する画像をふりわけるプラグインを使用して画像の切り替えを行います。

PCとスマートフォンなどのモバイル端末でレイアウトを最適化させる為の手法のひとつとしてレスポンシブレイアウトが使われるようになっているが、同じソースコードしてCSSなどでレイアウトを変更させるので作成は比較的用意だが、なにもしない場合は画像は双方で使用されてしまうため、グラフィックを多用するサイトではレイアウトは最適化してもデータ量は同じものとなってしまう。そこでデバイスによって使用する画像を切替えるようにしてスマートフォンでは軽量な画像を自動的に振り分けるようにしてみる。

今回作成したサンプル

【サンプル】PCとスマートフォンで画像を切り替える
http://www.html5-memo.com/sample/jq-books/18

※同じ画像ですが、画像内の文字が変わっていますのでPCやスマホで確認すると切り替わっているのが確認できます。

ブラウザの表示領域の大きさによって、表示する画像を切替えるプラグイン「breakpoint.js」

今回サンプルで導入する「breakpoint.js」はブラウザの表示領域(※以下、スクリーンサイズ)によって、img要素に読み込む画像を差し替えるもので、もともとは回線速度の状況によって読み込む画像を差し替える「hisrc.js」(https://github.com/teleject/hisrc)に込みこまれていたものが分離され同梱されているものだ。同様の仕組みでスタイル(CSS)を差し替えるメディアクエリー(mediaqueries/http://mediaqueri.es/)と利用方法は似ている。

また(正確にはこちらはbreakpointsと複数形だが)、同名のプラグインで「breakpoints.js」(http://xoxco.com/projects/code/breakpoints/)があり、こちらもスクリーンサイズをブレイクポイント(※切り替えポイント)として処理を分ける考え方は一緒であるが、ブレイクポイントの設定やブレイクポイント時の処理もJavascript上で記述する必要があるため、機能的ではあるが多少Javascriptの理解が必要になる。

一方、サンプルで利用している「breakpoint.js」は、基本的にはimg要素に独自data属性を記述することで設定が可能になるので、メンテナンス性には欠けるが、直感的で使いやすい。


Github内のhisrc.jsのページ(リポジトジ)。ここに同梱されているbreakpoint.jsを利用する。

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="js/breakpoint.js"></script>
<script src="js/script.js"></script>

デバイスによっての画像切り替え方法

デバイスによって画像を軽量化させる際に考えられるものとして、今回は2つの方法でサンプルを作成してみる。

ひとつは「画像サイズを変更させてファイルを軽量化させる方法」と、「同じ画像サイズで圧縮率を変更してファイルを軽量化させる方法」という2つを用意してみた。

HTMLソースコード

「breakpoint.js」の利用方法として、まず対象となるimg要素のsrc属性には一番軽量サイズの画像のリンクを記述し、スクリーンサイズごとに差し替える指示はHTML5のカスタムdata属性を記述していくことになる。

記述方法はメディアクエリーの書き方に似ており、スクリーンサイズが最大幅が320ピクセルの場合は、「data-maxwidth320px=”【読み込みたい画像のパス】”」のように記述する。このdata属性は一つのimg要素にいくらでも追加することができるので、様々なスクリーンサイズに対応した画像を指定することも可能だ。

またimg要素にwidthもheightも指定していないので、画像は基本的に縦横比を保ったまま幅(width)100%の状態で表示されることになるので、ブレイクポイント以外のスクリーンサイズ時には、画像が元サイズよりも拡大や縮小されて表示されるので注意してほしい。
画像が適宜拡大縮小されるのを避けたい場合は、CSSのメディアクエリと「breakpoint.js」のブレイクポイントを一緒にして、各ポイント時にimg要素に任意の固定幅を持たせれば、そのブレイクポイント以外では拡大縮小されないようにすることも可能だ。

<p><img class="resImg" src="img/01_s.jpg" data-minwidth321px="img/01_l.jpg"  alt=""></p>

<p><img class="resImg" src="img/02_s.jpg" data-minwidth321px="img/02_l.jpg"  alt=""></p>
(function(d,$){
 
  $(function(){
    $('.resImg').breakpoint();
  });

}(document, jQuery));

レスポンシブウェブデザインにおける「ピクセル密度(density)に基づいた解像度」の概念について

今回の「breakpoint.js」の利用方法は、レスポンシブウェブデザインには必須なviewportについてある程度理解しておく必要があるだろう。それぞれの解説や推奨設定などは関連書籍やネット上で紹介されていることが多いのでここでは詳しくは述べないが、「breakpoint.js」の指定方法にも関連している「ピクセル密度(density)に基づいた解像度」の概念について簡単まとめてみます。

様々なスクリーンサイズをもったデバイスが存在する昨今、制作者側として提供するサイズをどのサイズにするかが悩ましいところだ。かつて、デスクトップPCを前提で作られていたころは、ウェブサイトのコンテンツを960ピクセル幅で作成することがデファクトとなっていたが、現在何も設定しないで、そのようなウェブサイトをiphone5S(640×1136)で閲覧すると、幅640ピクセルの画面にサイト全体を表示できるようにコンテンツが約66%自動的に縮小されて表示されてしまう。

そこでコンテンツが自動縮小されないように、コンテンツの幅をピクセル固定にせずに相対的な単位(%など)にして作成した時に、CSSのwidth:100%の実質的なピクセル値の基準を、そのデバイスが持つ「ピクセル密度(density)に基づいた解像度」の幅とする設定が、viewportで設定する「width=device-width」になる。これはデバイスの向きによる変化にも柔軟に対応し、iphone5S縦の場合はwidth:100%の実質値は320ピクセルに、横の場合は568ピクセルになる。

iphone5S縦はデバイスの持つスクリーンサイズが本来幅640ピクセルのはずなのに、なぜwidth:100%が320ピクセル相当になるのかというと、viewportの「width=device-width」と指定することで、CSSのwidthやheightなどに指定されるピクセルの数値や計算は、例外を除いて全て「ピクセル密度(density)に基づいた解像度」を元に計算されることになるからだ。iphone5Sはretinaディスプレイでdensityの値は2に設定されていため、「ピクセル密度(density)に基づいた解像度」における幅100%は、640(ピクセル)÷2(density)=320(ピクセル)となる。

上記のように、viewportを「width=device-width」としたときは、寸法などの数値指定は全て「ピクセル密度(density)に基づいた解像度」によって計算がおこなわれるため、制作側は本来なら解像度の異なるiphoneのRetinaディスプレイと、非Retinaディスプレイに関して、それぞれサイズの異なるスタイルを作成しなくても良いということになる。

今回のbreakpoint.jsの数値の指定方法も「ピクセル密度(density)に基づいた解像度」によって行われるため、maxwidth=320pxと指定すれば、Retina、非Retinaそれぞれのiphoneに適用されるということになる。

最後に

レスポンシブWebの便利さとして1コードでPCとスマホに最適化させるということで、元の画像の圧縮率などで一枚で使用してしまったほうが楽で、ここまでするならばサーバーでPCとスマホに振り分けてそれぞれ最適化されたサイトを作ったほうがよいだろうと思う人もいると思いますが、jQueryでもこういったものができるよってサンプルとして見ていただければと思います。

今回は以上になります。

次回はクリックで展開するスライドメニューを作成したいと思います。

この記事を書いた人

著者 : ハヤシユタカ

2001年、有限会社ムーニーワークスを設立。WEB制作の他、書籍執筆、セミナー講演、企業研修などを行う。また、クリエイター育成機関デジタルハリウッドでは1999年より講師として本科WEBデザイナーコースやデジタルデザインコースを担当。 詳しいプロフィールはこちら

最近書いた記事

この記事に関連する記事