メディア掲載_Web Designing

Web Designing 2011年12月号

執筆:丸茂朋弘 執筆:丸茂朋弘

SmartphoneLab.2011年12月号

「viewport」の定番設定パターンを習得する

今月から始まった当Labでは、今や必須となりつつあるスマートフォン対応について、さまざまなノウハウをお届けする。さて、スマートフォンサイト制作の最初の関門といえるのが「viewport」だ。PCサイトには存在しない「窓」の概念を理解し、もろもろのパラメータを設定していくだけでも一苦労だ。しかし、実は現行のスマートフォンサイトで使われている「viewport」の設定パターンは、とても少ないのだ。今回は、定番ともいえる3つの設定パターンを紹介していこう。

スマートフォンサイト制作の最初の関門「viewport」を理解しよう

PCサイト制作者がスマートフォンサイトを制作する時に、まず最初につまずくポイントが「viewport」だろう。Webページをどのような大きさの「窓」を通して閲覧するかを設定するスマートフォン特有の概念だが、ページサイズや拡大サイズの指定と相まって、混乱してしまうことが多い(01)。
また、iPhoneとAndroidそれぞれのviewportの解釈に「クセ」があり、これを解消しようとすると、片方の不便な仕様をカバーするためにユーザビリティを犠牲にせざるを得ないなど、もどかしい部分もある。しかし、viewportの設定パターンは限られており、いくつかのパターンを習得してしまえば、制作において困ることはないはずだ(02)。

01viewportの概念

01 viewportの概念

「viewport」とは「覗き窓」という意味。どのような覗き窓から見るかによって、対象の見え方が変わってくる。スマートフォンの場合は、覗き窓そのものの大きさも変化する

02viewportの構文

02 viewportの構文

「viewport」とは「覗き窓」という意味。どのような覗き窓から見るかによって、対象の見え方が変わってくる。スマートフォンの場合は、覗き窓そのものの大きさも変化する

今回紹介する3パターンは、いずれも現行のサイトで採用されている設定パターンで、それぞれ一長一短の仕様がある。各々のサイトのコンテンツやデザインを考慮して、viewport設定を選択してほしい。
今回は、03のようなサンプルを例に、viewportの設定によって、OSごとにどのような違いがあるのかを解説する。

【viewportで設定できる値】

width
viewportの横幅(デフォルト:980px)
height
viewportの縦幅(デフォルト:auto)
initial-scale
ページ読み込み時の拡大率(デフォルト:1.0)
user-scalable
ユーザーによる拡大操作の許可(デフォルト:yes)
minimum-scale
拡大率の最小(デフォルト:0.25)
maximum-scale
拡大率の最大(デフォルト:1.6)
target-densitydpi
(Androidのみ)
viewportのdpi(デフォルト:medium-dpi)

widthは端末の幅を自動的に取得する「device-width」を指定可能。heightにも同様の値がある。initial-scaleはminimum-scaleとmaximum-scaleの間の値を指定する

03今回のサンプル

03 今回のサンプル

iPhoneでもAndroidでも、縦位置のときは、ほぼ同じレイアウト。viewportの設定によって、横位置にしたときの表示が変わってくる

SECTION1「表示幅固定」パターン

「表示幅固定」パターン

スマートフォンの縦位置時(ポートレートモード)と横位置時(ランドスケープモード)に同じレイアウトで表示したい時に用いるのが「表示幅固定」パターンだ。ディスプレイの縦横比が異なるため、多くの場合には横位置時ではズームが行われて幅いっぱいに表示される(中には、ズームしないサイトも存在する)。デザインの再現性は高いが、ページ全体に対する表示領域が狭い、画像がぼやけるなど、ユーザビリティに欠ける面もある。

「表示幅固定」パターンの仕様

「表示幅固定」パターンでは、縦位置時に表示したレイアウトをそのまま横位置時にも適用する(01)。横位置の場合、iPhoneでは1.5倍に、Androidでは端末のディスプレイサイズによって約1.5~1.8倍にズームされる。デザインをそのまま再現すればよいので、コーディング時の負担は軽いことが多い。

01「表示幅固定」パターンの例

01 「表示幅固定」パターンの例

NIKE FREE VOICE:http://nike.jp/nikefreevoice/
Xperia arcの横位置で表示すると、かなりの拡大率になる。画像を多用している場合、リキッドが効かないので、表示幅を固定しているサイトが多い

viewportとスタイルの設定

viewportの指定は02の通りだ。iPhoneでは、この指定だけで表示幅が固定される。ただし、Androidではディスプレイの幅以下の指定は無視されるため、横位置時にズームさせるには後述のJavaScriptを記述する必要がある。CSSでは大枠のwidthを320pxに指定し、フォントサイズをパーセントで指定して拡大に対応させる(03)。

02viewportの記述

02 viewportの記述

この記述により、たとえば320pxまでの幅の画像を横スクロールなしに表示できるようになる

03CSSの記述

03 CSSの記述

一番外側の要素の幅をviewportの指定と同値にする(01)。今回はフォントサイズの基準を12pxとし、この他の要素ではサイズをパーセントで指定している(02)

Androidへの対応

Androidではviewportの指定だけでは表示幅が固定されないので、JavaScriptで補完する必要がある。04のようなJavaScriptを使えば、resize/loadイベントからhtml要素の値を動的に指定できる。これにより、iPhoneとAndroidの両方で、縦位置でも横位置でもレイアウトを維持したまま幅いっぱいに表示される(05)。また、Androidの場合、コンテンツによっては拡大されすぎると見にくくなることがあるので、あえて拡大せずに、中央や左寄せで縦位置と同様のレイアウトを表示するサイトもある(06)。

04JavaScriptの記述

04 JavaScriptの記述

Androidでは、縦→横の動作を「resize」イベントで取得する

05表示例

05 表示例

「表示幅固定」パターンの横位置表示例。左がiPhoneの場合、右がAndroidの場合

06拡大せずにセンタリングされる例

06 拡大せずにセンタリングされる例

資生堂uno:http://www.shiseido.co.jp/uno/
iPhoneでは1.5倍のズームがかかるが、Androidでは縦位置での表示と変わらないので、センタリングされて表示される

SECTION2「リキッド」パターン

「リキッド」パターン

スマートフォンサイトで一番使われているのが、この「リキッド」パターンだ。縦位置時は「表示幅固定」と同じだが、横位置時にコンテンツが水平方向に広がる。基本的には縦→横にしても文字サイズは維持されるが、要素のサイズが変更されるため、デザインの再現性は低い。

「リキッド」パターンの仕様

「リキッド」パターンでは、ディスプレイサイズに合わせてコンテンツ全体の幅が変化する。「表示幅固定」とは異なり、横位置時でも文字サイズや画像サイズは変化せず、背景画像や背景色の繰り返しによって水平方向に拡大される(01)。

01「リキッド」パターンの例

01 「リキッド」パターンの例

NAVERのスマートフォンサイト:http://www.naver.jp/
表示幅が伸びる要素、中央による要素がある

スタイルの設定

コーディングの際には、左右に拡大される要素・中央に寄る要素・左右に寄る要素を確認し、floatで配置したり、幅をパーセント指定するなど、リキッドした際のレイアウトを常に意識しよう(02

02リキッドレイアウトのデザイン構成

02 リキッドレイアウトのデザイン構成

リキッドした際に、各要素がどこへどのように配置されるかをあらかじめ確認しておく。なお、繰り返しの効かない背景画像を使ったサイトなど、そもそもリキッドを適用できないデザインも存在するので注意が必要だ

viewportの設定

viewportを03のように指定すれば完成だ(04)。iPhoneは縦位置から横位置に切り替えた際に自動で1.5倍のズームがかかる仕様になっているが、「minimum-scale=1.0」と「maximum-scale=1.0」を指定すると回避できる。これによってユーザーによるズームも同時に使用できなくなってしまうが、そのためか現在のスマートフォンサイトではズームを禁止しているところが非常に多い。

03viewportの記述

03 viewportの記述

「minimum-scale=1.0」と「maximum-scale=1.0」の指定により、最小と最大のズーム率が「1.0」に固定されるため、iPhoneの自動ズームが禁止される。ちなみに、「user-scalable=no」を指定してもユーザーのピンチイン・ピンチアウトによるズームが禁止されるだけで、自動ズームは動作する

04表示例

04 表示例

「リキッド」パターンの横位置表示例。左がiPhoneの場合、右がAndroidの場合

SECTION3「ハイブリッド」パターン

「ハイブリッド」パターン

「表示幅固定」「リキッド」の両パターンは、iPhoneもしくはAndroidのいずれか一方にはスムーズに対応できるが、もう片方に対応するために、JavaScriptを読み込ませたり、ユーザーによるズームを犠牲にしたりしている。「ハイブリッド」パターンでは両者の長所を活かし、コーディングのシンプルさとユーザビリティを実現している。

「ハイブリッド」パターンの仕様

「ハイブリッド」パターンとは筆者が勝手に命名したものだが、要するに「表示幅固定」と「リキッド」をOSごとに使い分けるという意味だ。つまり、「リキッド」時に幅が1.5倍になってしまうiPhoneには「表示幅固定」を適用し、「表示幅固定」時にディスプレイサイズまでズームされないAndroidには「リキッド」を適用させるといった具合だ(01)。横位置時に両OSで見た目に差が出てしまうが、「ユーザーによるズーム」を活かしたまま、ディスプレイサイズに合った表示を実現できる。

01「ハイブリッド」パターンの例

01 「ハイブリッド」パターンの例

NTTドコモのスマートフォンサイト:http://www.nttdocomo.co.jp/
iPhone(上)とAndroid(下)で縦位置にしたときの見た目が違っているのがわかる

viewportとスタイルの設定

viewportは「表示幅固定」と同じように記述し(02)、あとは「リキッド」と同様にコーディングをする。これにより、横位置時には、iPhoneでは縦位置時と同じレイアウトを1.5倍で表示し、Androidではリキッドで表示する(03)。Androidの拡大/縮小ボタンによるズームには非対応となるが、ピンチイン・ピンチアウトによるズームには対応している。

02「ハイブリッド」パターンの例

02 「ハイブリッド」パターンの例

viewportの指定は「表示幅固定」と同じ

03表示例

03 表示例

iPhone(左)では1.5倍にズームして表示される。一方、Androidではサイズはそのままにリキッド状態で表示される

「リキッド」パターンでユーザーによるズームを実現させるには?

「リキッド」パターンでは、iPhoneの自動ズームを回避するために、viewportに「minimum-scale=1.0」と「maximumscale=1.0」を指定した。これによってユーザーによるズームも禁止されてしまうわけだが、JavaScriptを使って、限定的にズームを実現させることも可能だ。
Shi Chuan氏が制作したJavaScriptでは、ズーム禁止の状態から「最初の」マルチタッチ時にviewportを動的に書き換えることで、ユーザーによる拡大縮小を可能にしている。しかし、「最初の」とあるように、最初の1回しか効力がなく、倍率を1.0に戻して縦→横にすると、やはり自動ズームがかかってしまう。
Shi Chuan氏は「通常のユーザーは(スマートフォンサイトでは)ズームをしようとしない」ので、「1度ズームをすると(自動ズームの)問題が発生するが、大多数のユーザーはこの問題に遭遇するまでに至らない」と述べている。詳細は、Shi Chuan氏のページを参照してほしい。

A fix for iPhone viewport scale bug

A fix for iPhone viewport scale bug:
http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewport-scalebug/
HTML5 Boilerplate teamのメンバーでもあるShi Chuan氏のiPhone自動ズームに関する見解が記されている

お問い合わせはこちらからどうぞ