Media Queriesでの振り分けはpxではなくemが吉…かも
PC、スマホ、タブレット…、様々なデバイスに対応させるMedia Queriesの指定方法
スマホ用にサイトのCSSを再考していて気づいたこと。
現在、スマホやタブレット類では、
<meta name="viewport" content="width=device-width" />
などを指定するのがいわば常套手段になっている。
Viewportに"width=device-width"を指定した場合、RetinaのiPhoneでも(Viewportの物理的なピクセル値は640px*960pxであるが、過去のiPhoneとの後方互換をとって)あたかも320px*480pxであるかのように振る舞って表示する。 同様にiPadは768px*1024px。
一方、Androidの場合、そもそもViewportの値がバラバラ。
多くのスマホは320px*480pxか360px*640pxで表示するが、実はそれだけとも限らない。
タブレットも、Galaxy Tabなどは600px*1024pxだが、800px*1280pxのタブレットがあったり648px*1280pxのものがあったり、そうかと思えば、496px*1024pxとか480px*800pxなどもあるらしい。
また、Opera Mobileは拡大率を自分で設定できるので、Viewportに"width=device-width"を指定していても、device-widthの値としては「物理的なピクセル値 / 拡大率」の計算値を返している(ように見える)。
その上、BlackberryとかWindows PhoneとかKindleもあったり。
それぞれにportraitとlandscapeもあったりするし…。
もうどうすればいいのやら!?
参考:Mobile and Tablet Viewport Sizes with screen DPI and size | i-Skool
そのようなカオス的な状況の中、CSSのMedia Queriesを逐次書き連ねていくのは場当たり的で際限ないことになるし、はっきり言って面倒。
そこで発想を転換して、いっそ"px"での振り分けをやめてしまえばいいことに思い至った。
"px"の代わりに何を使うかというと、"em"。
ブラウザのfont-sizeを基準とした「画面幅」、要するに「文字数」を基準にすればいい。
(厳密には"rem"なのだろうが、Mobile SafariやChromeではMedia Queriesの判別に"rem"を指定すると無視するバグがあるし、Viewportのwidthを見る場合、"rem"も"em"も等しい)
具体例として、例えば次のようなHTML断片の3カラムのレイアウトを考えてみる。
<nav></nav> <article></article> <aside></aside>
CSSでのMedia Queriesは
/* 基本的な3カラム・レイアウト。navとasideは15%で可変幅。articleも可変幅 */ @media screen { nav { position : absolute; left : 0; top : 0; width : 15%; } article { margin : 0 15%; width : auto; } aside { position : absolute; right : 0; top : 0; width : 15%; } } /* 画面幅60em(60文字)までの3カラム。navとasideは9emで固定幅に。articleは可変幅 */ @media screen and (max-width : 60em) { nav, aside { width : 9em; } article { margin : 0 9em; } } /* 51em以下になると、asideが下に落ちて2カラム・レイアウトに */ @media screen and (max-width : 51em) { article { margin : 0 0 0 9em; } aside { position : static; width : 100%; } } /* 42em以下は1カラム */ @media screen and (max-width : 42em) { nav { position : static; width : 100%; } article { margin : 0; width : 100%; } }
現在、ブラウザの標準的なfont-sizeは16pxとなっていることが多いようだが(日本語用フォントの場合)、仮にユーザーがフォントサイズをデフォルト設定のままにしているとして、それぞれのケースにあてはめてみると…
- PC
- 基本的に3カラム。ブラウザのウィンドウ幅を狭くすればそれにあわせて2カラム、1カラムに
- iPhone
- 320px=20em、480px=30emとなるので、portraitもlandscapeも1カラムで表示
- iPad
- 768px=48emとなるのでportraitで2カラム、1024px=64emのlandscapeで3カラム
- Androidのスマホ(360px*640pxの場合)
- portraitもlandscapleも1カラム
- Galaxy Tab
- 600px=37.5emとなるので1カラム、landscapeで3カラム
と、こんな具合になる(はず)。
一方、ユーザーがフォントサイズを拡大・縮小していても、それにあわせて最適なレイアウトが適用される。 例えば、PCでブラウザのウィンドウ幅が同じ960pxだとしても、フォントを16pxで表示しているユーザーは60emなので3カラム、24pxで表示しているユーザーは40emなので1カラムでの表示になる。 スマホのOpera Mobileの人にも拡大率に合わせた表示を提供できる。
ということで、これならMedia Queriesでのブレークポイントを3カラム、2カラム、1カラムに変更したい3ヶ所で設定するだけで済むし、現状では例えばiPhoneは320px固定でもOKだが、もし将来的にOperaのように拡大率が指定できたりした際にも、何もせずともすでに対応できていることになるw
なお、大まかなブロック(コンテナ)のレイアウトでは"em"を基準に考えれば楽になるという話で、なにも"px"を一切使うなということではない。
例えば、navの中やarticleの中では自由に使えばいい。
念のため。
"Media Queriesでの振り分けはpxではなくemが吉…かも"へのTwitter上でのコメントやRT
6件のツイートがあります。
ツイート 1
asamuzaK.jp : Media Queriesでの振り分けはpxではなくemが吉…かも / PC、スマホ、タブレット…、Viewportの値がカオスな中、Media Queriesをどう指定すればいいのか http://t.co/l9gyIJdRK2
ツイート 2
実は、http://t.co/vh92LM6Y4Jではナビゲーション部分をdisplay:table-cellにしていたりするので、もう少し工夫(とさらにはDOMの助けもorz)が必要だった RT asamuzakjp http://t.co/l9gyIJdRK2
ツイート 3
“asamuzaK.jp : Media Queriesでの振り分けはpxではなくemが吉…かも” http://t.co/Bjfh0Ks9z8
ツイート 4
Opera MobileはViewportの拡大率を自分で設設定できて、Viewportの"width=device-width"には「物理的なピクセル値 / 拡大率」を返していた 今はどうか知らないけど… http://t.co/l9gyIJdRK2
ツイート 5
“asamuzaK.jp : Media Queriesでの振り分けはpxではなくemが吉…かも” https://t.co/aNyoRiFEoh
ツイート 6
つ asamuzaK.jp : Media Queriesでの振り分けはpxではなくemが吉…かも https://t.co/l9gyIJdRK2 https://t.co/IIYIShZPHv