- 可能であれば Chrome の文字拡大機能をサポートするために
rem
を使用する。 - ただし、実際に Chrome の文字拡大機能を「極大」にして検証することが必須条件。これに時間的・労働的なコストを割けないのなら
px
を使用したほうがいい。
「font-size
には rem
を使いましょう」という教えが独り歩きしており、実際に Chrome の文字拡大機能を「極大」にして検証していない人が多いため。
font-size
だけrem
を指定すればいいという訳ではなく、文字拡大に伴ったレイアウトの変更に耐えうる設計とする必要がある。つまり、font-size
だけでなく文字の拡大に依存する余白やサイズなどもフォントサイズを基準とした相対値(rem
やem
など)で指定する必要があるということ。- 以下はあるゆる箇所がアンチパターンであるものの、わかりやすい例として提示する。以下のようなコードだと文字拡大が起こった際にフォントサイズが親要素の高さを超えて切り取られてしまう。
.anti-pattern {
overflow: clip;
block-size: 30px;
font-size: calc(24 * var(--to-rem));
}
- また、別の理由として「
font-size
にはrem
を使いましょう」と言いつつも、:root
のfont-size
に16px
など絶対値を指定しており、 Chrome の文字拡大機能が動作していないというケースも見受けられた。実際に文字拡大機能を動かせば機能していないことは一目瞭然なはずなのだが、こちらから伝えるまでは分からなかったということは実際に文字拡大機能を動かして検証していない証拠だろう。
つまり、実際に文字拡大機能を動かして検証している実装者は少なく、文字拡大機能を動かした結果レイアウトが崩れる、文字が読めなくなる、良かれと思って相対値指定したのに全く機能していないという本末転倒な事態に陥っているケースが多い。
それならば px
指定をしたほうがレイアウト崩れの心配もなく、開発コスト的にも余計な労力を割かなくて良い。
答えは「No」である。
- 確かに余白やサイジング、ブレイクポイントなどの全てを
rem
などのフォントサイズを基準とした相対値で指定すれば、全てが拡大されるのでレイアウト崩れが起こることは少ない。 - だからといって全てを
rem
にすればいいかと言われると、そうではない。文字拡大機能ユーザーが望むことは行政の Web サイトにある文字拡大ボタンのような挙動であり、全てをズームしたいわけではないからである。 - 仮に全てをズームしたいのならズーム機能を利用するはずであり、ズーム機能との住み分けができていない。
そもそも相対値は何かを基準に指定したいから使うものであり、別に何も基準としたいものがない場合に使用するのはセマンティックとは呼べない。
- 例えば僕の身長は 182cm であるが、人に自分の身長を教える際にピカチュウの高さの 4.44 倍ですなんて言わない。普通であれば絶対値(cm)を答えるだろう。
- これと同じで、別に何も基準としたいものがない余白やサイジングをわざわざ「これは
font-size
の ◯ 倍です」と指定するのはおかしい。 - 原則的には絶対値の
px
をベースとして考えて、何かを基準にサイズ指定をしたい場合のみ相対値を使うのがベターではないか。
「段落の間は 1 文字分あけてください」「ボタンのpadding
は 1.5 文字分あけてください」というオーダーならem
を使うし、「数字リストは桁が増えた分に備えて数字 3 つ分幅を保ってください」というオーダーならch
を使う。至極単純な話であり、相対値とはこうあるものだろう。
コンポーネント間の余白やborder-radius
にrem
を用いる実装を見かけるが、それは本当にフォントサイズを基準としているか?は自問自答したい。
※ちなみに :root
の font-size
をハックしてリキッドレイアウトを組む実装が紹介されていたが、意味がわからないのでやらない。
rem
への変換方法には色々と方法があるが、calc()
関数で事足りるのでそれを使う。
@property --root-font-size {
syntax: "<length>";
inherits: false;
initial-value: 16px;
}
:root {
--to-rem: calc(tan(atan2(1px, var(--root-font-size))) * 1rem);
}
.heading {
font-size: calc(24 * var(--to-rem));
}
rem
の計算を簡略化するためにルートのfont-size
を 62.5%にするアプローチがあるが、使用しない。外部の CSS やサードパーティ製の CSS(特に WooCommerce や Shopify などのプラグインは顕著)がrem
ベースで指定されている場合に都合が悪い事態が起こり得るため。- Sass の関数を自作して効率化しなくても上記の
calc()
関数をスニペット登録すればコストは同じ。CSS 標準でできることは可能な限り CSS 標準でやったほうがいい。- また、誰も使っていないので知らない人は多いだろうが CSS 標準で 1 つ目のパラメータを 2 つ目のパラメータで割った余りを返す
rem()
という関数がある。Sass の変換関数はrem()
という命名がメジャーになっており、この全く関係のない CSS 標準の関数とバッティングすることは覚えておくと良い。
- また、誰も使っていないので知らない人は多いだろうが CSS 標準で 1 つ目のパラメータを 2 つ目のパラメータで割った余りを返す
上記の理由から実際に文字拡大機能を動かして検証を行い、かつ拡大時のレイアウト調整に時間的・労働的コストを掛けられる現場のみがrem
を使用するのが良い。
そこまでコスト掛けられないよって人はpx
を使用したほうが良い。
加えて CSS 初学者や CSS よくわからない人がこの検証フローを行うのは辛いと思うので、そういった方々もpx
を使用したほうがいい。