解 説

メディアクエリの設定でブレイクポイントの単位を「px」で指定することが多いと思いますが、「px」で指定するとSafariで思わぬ不具合に遭遇します。
これは2016年頃に広がったネタですが、いまだにSafariでは同様の結果になります。

結論から言うと、ベストプラクティスは「em」単位で指定することです。
「em」単位の求め方はこの場合、指定したいpx数を16で割るだけです。

ブレイクポイントの値は em で指定
この場合の計算は16で割るだけ
600pxにしたい場合は、600/16emとする

safariでの問題点

参考サンプル
このサンプルではブレイクポイントを600pxに指定しています。
これを600px/16pxで 37.5em と 37.5rem にした場合の検証用です。
赤がpx指定したもの、緑がem指定したもの、青がrem指定したものになります。
600px以上でopacityがかかって色が薄くなります。

HTMLコード

CSSコード

通常はchromeもfirefoxもsafariも問題ないです。どれも同じサイズの時に色が変わります。

html要素でfont-sizeを指定した場合

サンプル2
CSSに次の内容を追加します。

各要素に個別の指定がない限り、全てのフォントサイズが2倍になります。
そのため、「em」や「rem」指定した場合には、htmlに指定した200%に連動して600px幅でブレイクポイントが働かなくなりそうに思えます。けれども、実際はちゃんと600pxで色が変わります。
これは、「em」と「rem」はブラウザの「font-size」のベースに基づいているためです。

Media Queries Level 3の仕様では次のようになっています。

This media query expresses that style sheet is usable on screen and handheld devices if the width of the viewport is greater than 20em.

@media handheld and (min-width: 20em),
screen and (min-width: 20em) { … }
The ‘em’ value is relative to the initial value of ‘font-size’.

つまり、メディアクエリで使う’ em’値は ‘font-size’の初期値との相対値です。

けれども、この状態で safari では不具合が出ます。青色(rem指定したもの)だけ色が変わりません。
そして、ちょうど2倍のサイズの1200pxになったら変更されます。

どうやら、safariでは’font-size’の初期値ではなく、remだからhtml要素に指定した「font-size」の影響を受けています。
これはバグと言うよりもsafariの解釈の違いだと思います。というか、そもそも’font-size’の初期値との相対値というのが少し変な定義でもあります。’font-size’の初期値を変更するためにhtmlに指定を入れるはずだと思うのですが。。。

htmlに基準のfont-sizeを設定する場合は多く、またレスポンシブではこれを有効活用してレイアウトを変更する場合も多いです。しかもsafariはiPhoneユーザーに使われていますので予期しないバグになる恐れがあります。

そのような理由により、メディアクエリでは「rem」は使えません。

ブラウザでズームでの問題

これはブラウザのズーム機能を活用した場合に起こる問題です。
これもsafari特有の問題です。

これは最初のサンプルで試して見るとわかります。
safariでこのサンプルを表示してズームします。
この時safariで赤色のみ挙動が変わります。つまりsafariではpx指定した場合ズームした状態で閲覧するとメディアクエリが正常に働きません。
このことからpx単位は使わない方が良いのです。

さらに、ユーザーがブラウザでフォント設定を変更した場合も問題が生じます。

以上のことから「em」を使っておいた方が安心だということです。

これらの問題については以下の参考ページで詳細に語られていますので参考にしてください。

参考:PX, EM or REM Media Queries?

日本語訳したものがコリスさんのページにあります。