Skip to content

Instantly share code, notes, and snippets.

@tak-dcxi
Last active May 20, 2025 08:49
Show Gist options
  • Save tak-dcxi/aed0f8e331b6d7e87af99b9e6373b7af to your computer and use it in GitHub Desktop.
Save tak-dcxi/aed0f8e331b6d7e87af99b9e6373b7af to your computer and use it in GitHub Desktop.
font-size には rem を使うべきかどうかについての見解

font-size には rem を使うべきかどうかについての見解

結論

  • 可能であれば Chrome の文字拡大機能をサポートするためにremを使用する。
  • ただし、実際に Chrome の文字拡大機能を「極大」にして検証することが必須条件。これに時間的・労働的なコストを割けないのならpxを使用したほうがいい。

結論に至った背景

font-size には rem を使いましょう」という教えが独り歩きしており、実際に Chrome の文字拡大機能を「極大」にして検証していない人が多いため。

  • font-size だけ rem を指定すればいいという訳ではなく、文字拡大に伴ったレイアウトの変更に耐えうる設計とする必要がある。つまり、font-size だけでなく文字の拡大に依存する余白やサイズなどもフォントサイズを基準とした相対値(rememなど)で指定する必要があるということ。
  • 以下はあるゆる箇所がアンチパターンであるものの、わかりやすい例として提示する。以下のようなコードだと文字拡大が起こった際にフォントサイズが親要素の高さを超えて切り取られてしまう。
.anti-pattern {
  overflow: clip;
  block-size: 30px;
  font-size: calc(24 * var(--to-rem));
}
  • また、別の理由として「font-size には rem を使いましょう」と言いつつも、:rootfont-size16pxなど絶対値を指定しており、 Chrome の文字拡大機能が動作していないというケースも見受けられた。実際に文字拡大機能を動かせば機能していないことは一目瞭然なはずなのだが、こちらから伝えるまでは分からなかったということは実際に文字拡大機能を動かして検証していない証拠だろう。

つまり、実際に文字拡大機能を動かして検証している実装者は少なく、文字拡大機能を動かした結果レイアウトが崩れる、文字が読めなくなる、良かれと思って相対値指定したのに全く機能していないという本末転倒な事態に陥っているケースが多い

それならば px 指定をしたほうがレイアウト崩れの心配もなく、開発コスト的にも余計な労力を割かなくて良い。

全てを rem で指定すればいいのか?

答えは「No」である。

  • 確かに余白やサイジング、ブレイクポイントなどの全てをremなどのフォントサイズを基準とした相対値で指定すれば、全てが拡大されるのでレイアウト崩れが起こることは少ない。
  • だからといって全てをremにすればいいかと言われると、そうではない。文字拡大機能ユーザーが望むことは行政の Web サイトにある文字拡大ボタンのような挙動であり、全てをズームしたいわけではないからである。
  • 仮に全てをズームしたいのならズーム機能を利用するはずであり、ズーム機能との住み分けができていない。

そのサイズ指定は本当にフォントサイズを基準としたものか?

そもそも相対値は何かを基準に指定したいから使うものであり、別に何も基準としたいものがない場合に使用するのはセマンティックとは呼べない。

  • 例えば僕の身長は 182cm であるが、人に自分の身長を教える際にピカチュウの高さの 4.44 倍ですなんて言わない。普通であれば絶対値(cm)を答えるだろう。
  • これと同じで、別に何も基準としたいものがない余白やサイジングをわざわざ「これはfont-sizeの ◯ 倍です」と指定するのはおかしい。
  • 原則的には絶対値のpxをベースとして考えて、何かを基準にサイズ指定をしたい場合のみ相対値を使うのがベターではないか。

「段落の間は 1 文字分あけてください」「ボタンのpaddingは 1.5 文字分あけてください」というオーダーならemを使うし、「数字リストは桁が増えた分に備えて数字 3 つ分幅を保ってください」というオーダーならchを使う。至極単純な話であり、相対値とはこうあるものだろう。

コンポーネント間の余白やborder-radiusremを用いる実装を見かけるが、それは本当にフォントサイズを基準としているか?は自問自答したい。

※ちなみに :rootfont-size をハックしてリキッドレイアウトを組む実装が紹介されていたが、意味がわからないのでやらない。

rem への変換方法

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 標準の関数とバッティングすることは覚えておくと良い。

上記の理由から実際に文字拡大機能を動かして検証を行い、かつ拡大時のレイアウト調整に時間的・労働的コストを掛けられる現場のみがremを使用するのが良い

そこまでコスト掛けられないよって人はpxを使用したほうが良い。

加えて CSS 初学者や CSS よくわからない人がこの検証フローを行うのは辛いと思うので、そういった方々もpxを使用したほうがいい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment