第9回 CSS+jQueryでクロスデバイスサイトを作ろう

WebサイトをiPhone/Androidに最適化するには、PCサイトとは別にスマートフォン専用サイトを用意するのがベストですが、コストや時間などの理由で難しい場合があります。そこで今回は、PC向けのWebサイト(HTML)はそのまま利用し、CSSとJavaScriptだけでレイアウトやデザインを変更する「クロスデバイスサイト」の作り方を説明します。題材は、筆者が制作したiPhone/Android Webサイト制作出張セミナーのWebサイトです。

「iPhone/Android Webサイト制作出張セミナー」のサイト(PCからアクセスした場合)

 このサイトは1ページ完結の告知サイトで、左右2段組みで構成されています。左カラムにはナビゲーションメニューを、右カラムにはメインコンテンツを配置し、ナビゲーションメニューをクリックするとページ内リンクで表示する部分を変えられます。iPhone/Androidからアクセスしたとき、このページを以下のように表示するようにします。

iPhone/Androidからアクセスすると最適化されて表示される

PCサイトのマークアップ

 まず、ベースになるPCサイトのHTML/CSSを紹介します。クロスデバイス対応といってもそれほど特別なことはしていませんが、以下の点に注意します。

HTML/CSSを正しくマークアップする

 当然ですがHTMLは正しくマークアップし、バリデータでエラーを取り除いておきます。今回の作例はHTML5/CSS3でマークアップしましたが、(X)HTMLやCSSのバージョンは特に問いません。ただし、現状ではHTML5やCSS3を採用すると、Internet Explorerや古いブラウザーへの対応に手間がかかるので、PCサイトのターゲットブラウザーに応じて(X)HTML/CSSのバージョンを選択するとよいでしょう。

Safari/Chromeで確認する

 すでに説明したとおり、iPhone/AndroidのブラウザーはPC向けのSafari/Google Chromeと同じWebKitを採用しているので、SafariやChromeで正しく表示できなければiPhone/Androidでも意図したとおりに表示されない可能性が高くなります。PCサイトを制作する時点でもSafariとChromeで正しく表示されるか、必ず確認しましょう。

CSSでレイアウトする

 今回のサイトは、iPhone/Androidで閲覧したときにCSSとJavaScriptを使ってレイアウトを変更します。そのため、ベースになるPCサイトはいわゆるtableレイアウトではなく、CSSでレイアウトする必要があります。(X)HTMLはdiv要素などでマークアップし、CSSのfloatプロパティなどを使って配置します。

 実際のHTML/CSSは次のようになっています。

HTML(一部抜粋)


<!DOCTYPE HTML>
<html lang="ja">
<head>
<title>1日集中! iPhone/Android Webサイト制作出張セミナー | H2O Space.</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="_css/reset.css">
<link rel="stylesheet" href="_css/base.css">
</head>
<body>
    <div id="wrap">
        <header>
            <h1><img class="pngTr" src="_images/ttl_main.png" alt="1日集中! iPhone/Android Webサイト制作出張セミナー" width="948" height="309"></h1>
            <!-- 中略 -->
            </header>
            
        <div id="content" class="clearfix">
            <section id="areaSub">
                <nav>
                    <ul>
                        <li><a href="#about"><img src="_images/navi_about.png" alt="セミナー概要" width="250" height="45"></a></li>
                        <li><a href="#curriculum"><img src="_images/navi_curriculum.png" alt="カリキュラム" width="250" height="45"></a></li>
                        <li><a href="#instructor"><img src="_images/navi_instructor.png" alt="講師紹介" width="250" height="45"></a></li>
                        <li><a href="#price"><img src="_images/navi_price.png" alt="料金" width="250" height="45"></a></li>
                        <li><a href="#faq"><img src="_images/navi_faq.png" alt="よくあるご質問" width="250" height="45"></a></li>
                        <li><a href="#contact"><img src="_images/navi_contact.png" alt="お申込・お問合せ" width="250" height="45"></a></li>
                    </ul>
                </nav>
                <!-- 中略 -->
            </section>
            <section id="areaMain">
                <h2><img src="_images/ttl_intro.png" alt="はじめに" width="650" height="40"></h2>
                <article class="display">
                    <!-- 中略 -->
                </article>
                <h2 id="about"><img src="_images/ttl_about.png" alt="セミナー概要" width="650" height="45"></h2>
                <article>
                    <!-- 中略 -->
                </article>
                <h2 id="curriculum"><img src="_images/ttl_curriculum.png" width="650" height="45"></h2>
                <article>
                    <!-- 中略 -->
                </article>
                
                <h2 id="instructor"><img src="_images/ttl_instructor.png" width="650" height="45"></h2>
                <article id="areaInstructor">
                    <!-- 中略 -->
                </article>
                <h2 id="price"><img src="_images/ttl_price.png" alt="料金" width="650" height="45"></h2>
                <article>
                    <!-- 中略 -->
                </article>
                <h2 id="faq"><img src="_images/ttl_faq.png" alt="よくあるご質問" width="650" height="45"></h2>
                <article>
                    <!-- 中略 -->
                </article>
                <h2 id="contact"><img src="_images/ttl_contact.png" alt="お申込・お問合せ" width="650" height="45"></h2>
                <article>
                    <!-- 中略 -->
                </article>
                <p id="pageTop"><a href="#wrap"><img src="_images/btn_pagetop.png" width="24" height="130" alt="PAGE TOP"></a></p>
            </section>
<!-- / #content --></div>
<!-- / #wrap --></div>
    <footer>
        <div id="footerInner">
            <!-- 中略 -->
        </div>
    </footer>
</body>
</html>


CSS(一部抜粋)


body {
    background: url(../_images/bg_main.png) left top repeat-x;
    color: #333;
    line-height: 1.5;
}
#wrap {
    width: 1000px;
    margin: 0 auto;
}
/* header */
header {
    position: relative;
}
h1 {
    z-index: 10;
    position: relative;
}
/* content */
#content {
    margin: -10px 9px 50px;
    width: 930px;
}
/* #areaMain */
#areaMain {
    width: 650px;
    float: right;
    padding: 10px 0;
    background-color: #fff;
    border-radius: 8px;
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    position: relative;
}
#areaMain h2 {
    margin: 20px 0 10px;
}
#areaMain article {
    padding: 0 15px;
}
#pageTop {
    position: absolute;
    left: 650px;
    top: 1800px;
}
/* nav */
#areaSub {
    position: absolute;
    top: 304px;
}
nav {
    padding: 14px 0;
    background-color: #009ce2;
    width: 250px;
    margin-bottom: 10px;
}
nav li img {
    vertical-align: top;
    border-bottom: 1px solid #e0e0e0;
}
/* footer */
footer {
    clear: both;
    background: url(../_images/bg_footer.png) left top repeat-x;
}
#footerInner {
    width: 930px;
    margin: 0 auto;
    padding: 30px 0;
}


そのほかの注意点

 PCサイトをCSSとJavaScriptでスマートフォンに最適化する場合は、以下の点にも注意します。

フレームを使わない

 フレーム(frameset要素/iframe要素)を使うと、CSSやJavaScriptでレイアウト調整ができず、クロスデバイス対応が難しくなります。また、iPhoneのSafariはフレームのスクロールバーが表示されず、フレーム内のスクロール操作が難しいので(2本指を使って操作します)、使い勝手の面でも好ましくありません。新規サイトの場合はフレームは使わずに構築し、フレームを使っている既存サイトの場合はマークアップの変更を検討しましょう。

画像文字の使用はなるべく抑える

 見出しなどに画像化した文字を使っていると、スマートフォン向けに文字サイズなどを調整したときに、見出しよりも本文が大きくなってしまうなどバランスが全体的に崩れてしまいがちです。文字情報はなるべく画像ではなくテキストとして作成しましょう。どうしてもデザイン性を重視する必要がある場合は、サーバー上のフォントデータをダウンロードして表示する「Webフォント」を活用するのも手です(日本語の対応はこれからに期待ですが)。

メディアクエリーでページ幅を調整する

 「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端末の幅と高さ
orientationportraitまたはlandscapeでブラウザーの縦横のどちらが長いかを指定する。スマートフォンにおいては本体の向きが縦か横かを判別できる
aspect-ratio、device-aspect-ratio幅と高さの比
colorデバイスの色数の表示能力
color-index端末のカラーテーブルのエントリ数
monochromeモノクロームフレームバッファにおける階調数
resolution端末の解像度
scanTVでの操作処理方法を指定する(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サイトのリニューアル案件も増えてくるかも知れません。ぜひ今回紹介したテクニックを参考に実践してみてください。


Comments