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

ツイート 2

ツイート 3

ツイート 4

ツイート 5

ツイート 6