株式会社オンラインの金沢です。今回は、前回に引き続きスマホ対応の件について書きたいと思います。
スマホ対応の仕方は大きく分けて2種類あります。
- 画面サイズによりレイアウトを変更する方法
- デバイスの種類により表示ソースを変更する方法
1の画面サイズはCSSかJavaScriptで識別します。2のデバイスの種類はPHPで識別可能です。今回は1のCSSとJavaScriptを用いた方法について紹介させて頂きます。ちなみに、当ホームページも1の方法でスマホ対応にしております。
はじめに、画面幅を指定するviewport設定
CSSやJavaScriptはブラウザ側で処理が行われるので、画面幅を取得することができます。画面幅を取得する前に、まずは幅を正しく読み取るように設定する必要があります。それがviewport設定です。もともとスマートフォンのブラウザは、ページを横幅980pxと仮定して表示してしまうため文字や要素が縮小されてしまいます。そこで、HTMLのheadの中にmeta要素でviewportを設定すれば、表示幅を指定することができます。
<meta name="viewport" content="width=device-width" />
「width=device-width」と指定することで画面幅を表示幅に指定することができますので、これだけでもだいぶ見やすくなります。
CSSでレスポンシブにレイアウトを調整しましょう
viewportを設定していても、CSSの「width」に表示幅以上の値を指定していては要素がはみ出てしまいます。そのような要素は、表示幅が小さくなったときに「width: 100%;」と指定するようにCSSを追加しましょう。CSSはあまり詳しく勉強しておりませんが、下記のようなコードで画面幅ごとにスタイルを振り分けることができます。
@media only screen and (max-width: 940px) and (min-width: 651px) { /* ここに画面幅が940px以下、651px以上の場合のCSSを記述する */ } @media only screen and (min-width: 650px) { /* ここには画面幅が650px以下の場合のCSSを記述する */ }
このように記述することで「max-width」以下、「min-width」以上の画面幅を指定してスタイルを付けることができます。「max-width」、「min-width」のどちらか一方のみの指定も可能です。
widthを指定し直すだけではなく、「float: none;」と指定して回り込みを解除したり、「margin」や「padding」を調整したりなど、もとのデザインによって書き加えるべきCSSは様々になります。
「width: 100%」としたときに、「padding」や「border」があると要素がはみ出してしまうことが多いですが、そのときに便利なCSSプロパティが「box-sizing」です。「box-sizing」を「border-box」と指定することで、「padding」と「border」を含んだ横幅が「width」で指定した値になります。但し、ブラウザごとにプロパティ名が「-webkit-box-sizing」と異なるものもあります。まとめたものが下記のサイトにありましたので、ご覧下さい。
・CSS3 の box-sizing が便利すぎる!! padding や border に依存しない width, height 指定 | TM Life
かゆい所に手が届くJavaScript
CSSでは対応しきれない場合はJavaScriptで解決できることがあります。JavsScriptでは「window」オブジェクトの「innerWidth」プロパティで画面幅を取得できます。
if ( window.innerWidth > 940 ) { /* ここに画面幅が941px以上の場合のスクリプトを記述する */ } else { /* ここには画面幅が940px以下の場合のスクリプトを記述する */ }
これで、メニューをドロップダウン式に変更したり、要素の位置を移動させたりなど、かゆい所に手が届くようになります。jQueryを使えば簡単にできます。参考までにjQueryを使った例が下記のスクリプトです。
if ( window.innerWidth < 651 ) { /* メニューをドロップダウン式に */ $( '#nav-icon' ).css( 'display', 'block' ); $( '#nav-menu' ).css( 'display', 'none' ); $( document ).on( 'click', '#menu-icon', function() { $( '#nav-menu:not( :animated )' ).toggle( 'slow' ); } ); /* サイドバーをメインの後ろに */ var sidebar = $( '#sidebar' ); $( '#main' ).after( sidebar ); }
最初のif文により画面幅650px以下で動作します。jQueryの「toggle」メソッドは、その要素のCSSプロパティ「display」が「none」であれば「block」に、それ以外であれば「none」に変更させます。しかもアニメーション付きです。従って、あらかじめCSSで「#menu-icon { display: none; }」を指定しておき、画面幅が小さくなったら「#menu-icon」の「display」を「block」に、「#nav-menu」の「display」を「none」にします。これで、「#menu-icon」の要素をクリック(タップ)すると「#nav-menu」の要素がアニメーションで現れます。「toggle」メソッドを呼び出す要素のセレクタに「:not( :animated )」が付いているのは、アニメーション中はクリックしても反応しないようにするためです。
jQueryの「after」メソッドは、その要素の後ろに引数の要素を追加します。引数がHTML要素から取得したものであれば、もとの位置にあった要素を消してくれますので、たったこれだけで移動が完了になります。
但し、あまりJavaScriptを作動させすぎるとブラウザ側で処理が重くなりますので、やりすぎには注意しましょう。
まとめ
手順を簡略してまとめますと
- HTMLでviewport設定
- CSSコードを追加
- 必要であればJavaScriptを記述する
となります。デザインはもとのものを引き継ぐことができますので、私のようにデザインをやれない者でもCSSの知識があればそれなりに仕上がります。当ホームページに使わせて頂いたCSSテンプレート(4月6日の記事参照)はスマホ対応しておりませんでしたが、これらのノウハウでスマホ対応にしました。
しかし、デメリットもいくつかあります。この方法でサーバーから送信されるデータはPCとスマホ両方の分が入っていることになるため、多少大きくなってしまいます。通信時間を改善させることもサイトの品質にも関わりますので、効率的な記述にすることが課題となるでしょう。また、CSSやJavaScriptはブラウザで処理をする以上、重くなるとデバイスへの負担が大きくなってしまいます。スマートフォンはPCに比べると、まだまだ処理性能が劣るところがありますので、処理時間が長くなってしまいます。ユーザーに快適にご利用して頂くためにも、できるだけ軽くサイトを作成するように、今後も心掛けます。
金沢