CSS 文字拡大と相対単位ルール
この skill は、font-size を rem にするべきか px にするべきか、その判断条件を揃えるためのものです。
主眼は Chrome の文字拡大機能に耐えることと、文字サイズに本当に従属する値だけを相対単位にすることです。
ブレイクポイントやビューポート基準のレスポンシブ判断は ../kf-g-css-tak-responsive-rules/SKILL.md を優先し、この skill では文字と文字依存寸法に絞って扱います。
この skill を使う場面
font-sizeをremとpxのどちらで指定するか決めるとき- Chrome の文字拡大機能をサポートすべきか、どこまで検証するか決めるとき
- 文字拡大時に
paddinggapinline-sizeblock-sizeなどを追従させるべきか判断するとき remの一括変換、:rootのfont-sizeハック、62.5%運用をレビューするときemchを使うべき箇所と、単にpxのままにすべき箇所を切り分けるとき- AI が生成した CSS に「とりあえず全部
rem」の実装が混ざっていないか確認するとき
最初に決めること
- Chrome の文字拡大機能を「極大」まで使って検証し、崩れを直すコストを確保できるか。
- その値は本当に文字サイズを基準に変化させたい値か。
- ユーザーが必要としているのは文字だけの拡大か、ページ全体のズームか。
判断順序
まずは px を基準に考える
- 原則として、基準が無いサイズ指定は
pxを基準に考える。 - 相対値は「何を基準にしたいか」が明確な場合にだけ使う。
- 文字サイズを基準にする意味がないコンポーネント間余白、装飾的な
border-radius、なんとなくの固定サイズを、習慣だけでremにしない。 - 文字拡大の検証フローを維持できない体制、または CSS の運用に不慣れな体制では、無理に
remを採用しない。
rem を使ってよい条件
- Chrome の文字拡大機能をサポートしたい
font-sizeにはremを使ってよい。 - ただし、
font-sizeだけremにして終わりではない。文字拡大に伴って増えるべき余白やサイズも、必要に応じて相対値にする。 remを採用するなら、Chrome の文字拡大機能を実際に「極大」まで上げて検証することを必須にする。- 文字が増えても読める、切り取られない、操作できる、という状態まで責任を持てる場合だけ
remを使う。 :rootのfont-sizeを絶対値で固定して、見かけだけremを使う実装はしない。
em と ch を使う条件
emは、その要素自身の文字サイズを基準にしたい値へ使う。- 例として、「段落間は 1 文字分」「ボタンの
paddingは 1.5 文字分」のように、文字数や文字サイズが意味そのものになっているときはemが自然である。 chは、数字や等幅に近い文字数を基準にしたい幅へ使う。- 例として、「数字リストは 3 桁分の幅を確保する」のような要件には
chを使う。 - 文字サイズとの関係が要素ローカルで完結するなら、何でも
remにせずemやchを優先する。
px を選び直す条件
- 文字拡大の「極大」検証に時間的、労働的コストを割けない。
remにしたことでレイアウト崩れや可読性低下が起きても、修正責任を持てない。- その値が本当は文字サイズを基準にしておらず、単に「相対値のほうが良さそう」という理由しかない。
- 実装者やチームが文字拡大とズームの違いを整理できておらず、相対単位の適用範囲を判断できない。
Chrome の文字拡大で確認すること
font-sizeだけでなく、文字拡大で影響を受ける余白やサイズが破綻しないか確認する。- 固定
block-size、固定inline-size、overflow: clip、強い切り詰めが、文字の切り取りを起こしていないか確認する。 - ボタン、フォーム、チップ、ナビゲーションなど、文字量が増えると操作性が落ちやすい要素を優先的に確認する。
- 複数行化、折り返し、行送り、隣接要素との衝突を確認する。
- ユーザーが求めているのは行政サイトの文字拡大ボタンに近い挙動であり、ページ全体のズームではないことを前提にする。
- ページ全体を拡大したい要求はブラウザズームの責務であり、文字拡大対応のために何でも拡大させない。
.anti-pattern {
overflow: clip;
block-size: 30px;
font-size: calc(24 / 16 * 1rem);
}
- 上のように固定高さと切り取りを残したまま
font-sizeだけrem化すると、文字拡大時に読めなくなる。
禁止事項
font-sizeだけremにして、周辺の文字依存寸法をすべてpxのまま放置しない。- 逆に、文字サイズを基準にする意味がない値まで一律に
remにしない。 :rootのfont-sizeをハックしてリキッドレイアウトを組まない。- 文字拡大のためにブレイクポイント設計までこの skill に持ち込まない。ブレイクポイントの単位選定は ../kf-g-css-tak-responsive-rules/SKILL.md を参照する。
- Sass などで
rem()という独自変換関数を安易に作らない。CSS 標準のrem()関数名と衝突するためである。
rem への変換方法
- px 由来の値を
remに直すときはcalc()を使い、値の由来を残す。 - 変換を何度も書く現場では、CSS 標準だけで組める変換ヘルパーを使ってよい。
- 変換を Sass 関数へ逃がす前に、CSS 標準の範囲で完結できないかを確認する。
@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));
}
- このヘルパーは値変換のためのものであり、実際の
:rootのfont-sizeを固定するためのものではない。
出力時の方針
- まず
rempxemchのどれで扱うべきかを明示する。 remを選ぶ場合は、Chrome の文字拡大をどこまで検証するか、どの寸法を追従させるかを明示する。pxを選ぶ場合は、なぜ相対単位の基準が成立していないのかを短く説明する。emchを選ぶ場合は、何を基準にしているのかを要件と結び付けて説明する。- 既存コードへ禁止事項がある場合は、単に書き換えるだけでなく、何が危ないのかも短く説明する。
最終チェック
- 文字拡大をサポートするなら、Chrome の文字拡大機能を「極大」まで実際に確認したか。
- 相対単位を使っている値に、文字サイズ基準の意味があるか。
font-sizeだけでなく、文字依存寸法の追従要否を確認したか。- 固定高さや切り取りが、文字の可読性を壊していないか。
- なんとなくの一括
rem化になっていないか。 emchを使うべき局所要件を、安易にremで潰していないか。- 文字拡大とページズームの責務を混同していないか。