WebサイトをiPhone/Androidに最適化するには、PCサイトとは別にスマートフォン専用サイトを用意するのがベストですが、コストや時間などの理由で難しい場合があります。そこで今回は、PC向けのWebサイト(HTML)はそのまま利用し、CSSとJavaScriptだけでレイアウトやデザインを変更する「クロスデバイスサイト」の作り方を説明します。題材は、筆者が制作した「iPhone/Android Webサイト制作出張セミナー」のWebサイトです。
このサイトは1ページ完結の告知サイトで、左右2段組みで構成されています。左カラムにはナビゲーションメニューを、右カラムにはメインコンテンツを配置し、ナビゲーションメニューをクリックするとページ内リンクで表示する部分を変えられます。iPhone/Androidからアクセスしたとき、このページを以下のように表示するようにします。
当然ですがHTMLは正しくマークアップし、バリデータでエラーを取り除いておきます。今回の作例はHTML5/CSS3でマークアップしましたが、(X)HTMLやCSSのバージョンは特に問いません。ただし、現状ではHTML5やCSS3を採用すると、Internet Explorerや古いブラウザーへの対応に手間がかかるので、PCサイトのターゲットブラウザーに応じて(X)HTML/CSSのバージョンを選択するとよいでしょう。
すでに説明したとおり、iPhone/AndroidのブラウザーはPC向けのSafari/Google Chromeと同じWebKitを採用しているので、SafariやChromeで正しく表示できなければiPhone/Androidでも意図したとおりに表示されない可能性が高くなります。PCサイトを制作する時点でもSafariとChromeで正しく表示されるか、必ず確認しましょう。
今回のサイトは、iPhone/Androidで閲覧したときにCSSとJavaScriptを使ってレイアウトを変更します。そのため、ベースになるPCサイトはいわゆるtableレイアウトではなく、CSSでレイアウトする必要があります。(X)HTMLはdiv要素などでマークアップし、CSSのfloatプロパティなどを使って配置します。
メディアクエリーでページ幅を調整する
「iPhone/Android Webサイト制作出張セミナー」のサイトは横幅が950pxあるので、画面が小さく解像度の低いスマートフォンで表示すると、文字が非常に小さく見づらくなります。
そこで、次のような専用のCSSを用意し、iPhone/Androidから閲覧した場合は左カラム(ナビゲーションメニュー)を非表示にし、右カラム(メインカラム)だけを表示するようにします。
#wrap {
width: 680px;
}
#areaSub {
display: none;
}
#content {
width: 650px;
}
 |
---|
左カラムは非表示に、右カラムと全体の幅を狭く変更する |
ナビゲーション部分(#areaSub)のdisplayプロパティを「none」にすることで非表示にし、メインカラム(#content)や外側の枠(#wrap)の幅をスマートフォンに合わせて狭めます。外側の枠の横幅はiPhone 3GSの解像度(320ピクセル)に合わせるのが理想ですが、今回は680pxに設定して、後ほどViewportで画面サイズに合わせて縮小して表示します。
このCSSは、「メディアクエリー」を使ってスマートフォンから閲覧された場合にのみ適用します。
メディアクエリーとは
メディアクエリーは、出力する媒体(PC、印刷など)や画面解像度などの条件に合わせてスタイルを適用できるCSS3の機能です。メディアクエリーの指定方法はいくつかありますが、今回はCSSファイルにリンクするlink要素のmedia属性を使います。
まず、前に作成したiPhone/Android向けのスタイルを「iphone.css」などのファイルに書き込んで保存します。このファイルにリンクするにはhead要素に次のように記述します。
<link rel="stylesheet" href="_css/iphone.css">
メディアクエリーを使ってスマートフォンだけを対象に適用するには、media属性を付加して次のように記述します。
<link rel="stylesheet" href="_css/iphone.css" media="only screen and (max-device-width: 480px)">
この記述によってiphone.cssは、「画面への表示でかつ、端末の解像度が480px以下の場合」にのみ読み込まれます。max-device-widthは「媒体特性」と呼ばれる設定項目の1つで、以下のような種類があります。
width、height | 解像度。PCのブラウザーなどの場合はウィンドウサイズで変化する |
device-width、device-height | 端末の幅と高さ |
orientation | portraitまたはlandscapeでブラウザーの縦横のどちらが長いかを指定する。スマートフォンにおいては本体の向きが縦か横かを判別できる |
aspect-ratio、device-aspect-ratio | 幅と高さの比 |
color | デバイスの色数の表示能力 |
color-index | 端末のカラーテーブルのエントリ数 |
monochrome | モノクロームフレームバッファにおける階調数 |
resolution | 端末の解像度 |
scan | TVでの操作処理方法を指定する(progressiveなど) |
grid | グリッドベースの端末であることを示す |
これらの値を組み合わせて、スタイルを適用する対象を複雑な条件で絞り込めます。
なお、メディアクエリーを使ったlink要素は、メディアクエリーを解釈できないIE6~8ではそのまま読み込まれてしまう場合があります。そこで、以下のようにコンディショナルコメントを記述し、ブラウザーがIE以外の場合にだけ読み込むようにします。
<!--[if !IE]>-->
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="_css/iphone.css">
<!--<![endif]-->
メディアクエリーのそのほかの利用方法
今回はlink要素でメディアクエリーを利用しましたが、以下のような方法でCSSファイル内でも利用できます。
@importで適用する
CSS内で他のファイルを読み込む@importでは、次のようにメディアクエリーを利用できます。
@import url(color.css) screen and (max-device-width: 480px);
@mediaで利用する
CSSプロパティの定義部分では、@mediaでメディアクエリーを利用できます。
@media (max-device-width: 480px) {
}
Viewportを調整する
メディアクエリーを使ってページの幅は調整できましたが、実際にiPhoneで確認してみると右側に余白がある状態で表示されます。これはViewportにより、デフォルトでは横幅980ピクセルの仮想ウィンドウを縮小した状態で表示されるためです(関連記事)。
そこで、次のような記述をhead要素に追加して、Viewportを適切な値に設定します。
<meta name="viewport" content="width=680; initial-scale=0.47; user-scalable=yes">
スマートフォン専用サイトではwidthをdevice-widthに設定しましたが、今回はCSS(iphone.css)で設定した値と同じ680ピクセルに固定しています。基本的にはこれでディスプレイが680ピクセル想定になり、正しく表示されるはずですが、iPhoneでは初期の倍率を指定する「initial-scale」の値を「1」にすると、widthの指定が無効になります。これはどうやらiPhoneのバグのようです。そこで、現状ではinitial-scaleは320/680*100=47%で「0.47」と指定しておきます(Androidでもこのままで正しく表示されました)。また、「user-scalable」を「yes」に設定しているので、ユーザーが自由に拡大できます。
見出しとナビゲーションを兼用するパネル
スマートフォン向けのiphone.cssでは左カラムを非表示にしたので、この状態ではページ内にナビゲーションが存在していません。スマートフォン向けのナビゲーションを新たに作成しても構いませんが、今回は1ページのみのサイトなので、見出しとナビゲーションを兼用するパネル型のUIを実装してみましょう。本文をいったん隠しておき、各見出し部分をタップすると本文が縦方向に展開して表示されるようにします。
 |
|  |
---|
アコーディオンパネルでタイトルとナビゲーションを兼用する |
まず、次のようなCSSで本文を隠します。
article:not(.display) {
display: none;
}
HTMLでは本文をarticle要素でマークアップしているので、基本的にはarticleのdisplayプロパティをnoneに変更するだけです。ただし、「はじめに」という項目の本文だけは最初から表示させておきたいので、「はじめに」のartilce要素には「display」というclass名を付けておき、CSS3の:notセレクターを使って.displayを除外しています。
続いて、JavaScriptを使って見出し部分をタップしたときの処理を記述します。今回はjQueryを利用して記述します。
$('h2').click(function() {
$(this).next().slideToggle('fast');
});
h2要素をクリックしたとき、HTMLで自身(this)の次に登場する要素(ここではarticle要素)を、スライドダウンのエフェクトで表示させます。これによって、非表示だった本文部分がスライドしながら表示されます。slideToggle()は表示/非表示を交互に切り替えるメソッドですので、もう一度タップすると今度は本文が隠れます。こうして、見出しとナビゲーションを兼用するパネルができました。
タイトル画像を調整する
「iPhone/Android Webサイト制作出張セミナー」のサイトは、タイトル画像をページ幅いっぱい(幅948ピクセル)で作成してあるので、そのままではスマートフォンで表示しきれません。そこで、以下のようにスマートフォン向けに幅665ピクセルに縮小したタイトル画像を用意します。
 |
---|
PCサイト用の画像。948ピクセルで作成 |
 |
---|
スマートフォン用の画像。幅665ピクセルで作成 |
次に、jQueryを使って画像を切り替える処理を記述します。
if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0)) {
$('h1>img').attr('src', '_images/ttl_main_mini.png').attr('width', '665').attr('height', '217');
}
条件分岐のプログラムは前回解説したとおり、スマートフォンからのアクセスをユーザーエージェントを見て判別しています。条件に合致した場合に、h1要素内のimg要素、つまりタイトル画像のsrc、width、height属性をそれぞれ書き換えています。
CSSを使った画像の切り替え
本文ではjQueryを使った方法を紹介しましたが、CSSとメディアクエリーを使って切り替えることもできます。その場合は、HTMLではスマートフォン用とPC用のタイトル画像を並べて配置して、スタイルシートで隠しておきます。たとえば、class属性に「iphone」と指定して、displayプロパティで非表示にします。
<h1>
<img src="_images/ttl_main.png" alt="1日集中! iPhone/Android Webサイト制作出張セミナー" width="948" height="309">
<img class="iphone" src="_images/ttl_main_mini.png" alt="1日集中! iPhone/Android Webサイト制作出張セミナー" width="665" height="217">
</h1>
.iphone {
display: none;
}
次に、メディアクエリーで読み込んだスマートフォン専用のスタイルシート(iphone.css)で、.iphoneのdisplayプロパティを変更します。
.iphone {
display: block;
}
同時に、PC用のタイトル画像を非表示にします。
h1>img {
display: none;
}
「>」はCSS3のセレクターで、「一番初めの子要素」という意味です。ここでは、h1要素内で初めに登場するimg要素、つまりPC向けのタイトル画像に絞り込めます。
これで、タイトル画像をPCとスマートフォンとで切り替えられました。ただし、この方法はCSSが利用できない環境(音声ブラウザーなど)ではタイトルが2回存在することになり、あまり好ましくありません。スクリプト言語が利用できない環境などでの妥協策として利用しましょう。
PHPを使った画像の変更
本文では、スマートフォン用の画像を別途用意していましたが、PHPなどのサーバーサイドのスクリプト言語を利用すると、より柔軟な運用ができます。たとえばPHPには画像をプログラムで加工できる「GDライブラリ」という仕組みがあり、画像のサイズをプログラムだけで変更できます。
GDライブラリの利用方法はサーバーの設定によって異なり、利用方法も高度なのでここでの説明は割愛します。ほかにも、FlickrやPicasaなどのオンラインアルバムサービスのAPIを使ったり、WordPressなどのCMSと組み合わせたりして、画像サイズを自動的に変更する方法もあります。
電話番号リンクの変更
ここまででレイアウトの調整が完了したので、今度はスマートフォンからのアクセスの場合に使い勝手をよくする工夫をしましょう。最初に、スマートフォンから手軽に電話をかけられるように、ページ内の電話番号にリンクを設定します。iPhoneでは電話番号らしき数字の組み合わせに自動的にリンクが張られますが、正しく認識されないことも多いので自動リンク機能をmeta要素で無効にします。
<meta name="format-detection" content="telephone=no">
次に、電話番号の前後を以下のようにspan要素でマークアップします。
<p> お電話の場合は「<span id="tel">050-5532-9224</span>(Skype電話直通)」までお問合せください。留守番電話(ボイスメール)になることがありますので、その際はお名前とお電話番号を残していただければ幸いです。 </p>
最後に、jQueryを使って次のようなスクリプトを追加し、電話番号にリンクを張ります。
$('h1>img').attr('src', '_images/ttl_main_mini.png').attr('width', '665').attr('height', '217');
$('#tel').html('<a href="tel:' + $('#tel').html() + '">' + $('#tel').html() + '</a>');
これでspan要素の中身がa要素で書き換えられ、telリンクが設置されます。
問い合わせボタンの挙動の変更
PC用のページは「お申込・お問合せ」ボタンをクリックすると入力フォームに移動しますが、スマートフォンの場合はフォーム入力がしづらいので、今回はフォームの代わりにメーラーを起動させます。スクリプト部分を以下のように変更します。
$('h1>img').attr('src', '_images/ttl_main_mini.png').attr('width', '665').attr('height', '217');
$('#tel').html('<a href="tel:' + $('#tel').html() + '">' + $('#tel').html() + '</a>');
$('#areaContact a').attr('href', 'mailto:support@h2o-space.com?subject=' + encodeURI('iPhone/Androidサイト制作セミナーについて'));
a要素のhref属性を書き換え、mailto:のリンクに変更しています。これで、「iPhone/Androidサイト制作セミナーについて」という件名の電子メールが送信できるようになります。
 |
---|
メールが送信できるようになる |
◆
スマートフォン向けサイトを作るときにもっとも多いのが、「既存のPCサイトをそのままスマートフォンでも見やすくしたい」という要望かもしれません。しかし、もともとPCサイト向けに制作したサイトをスマートフォンに最適化するのは実際にはかなり手間のかかる作業です。今後は、スマートフォン対応を意識したPCサイトのリニューアル案件も増えてくるかも知れません。ぜひ今回紹介したテクニックを参考に実践してみてください。