sizing-units について
sizing-units は、CSS のサイズ単位の選び方を扱うデザイン Skill です。インターフェースを設計・レビューする開発者向けに、テキスト、画面、利用可能な空間に応じた単位選択とアクセシビリティの確認項目を示します。
主な機能
- 01対象に応じた単位の選択
- 02rem と px の使い分けを説明
- 03レイアウトに相対単位を使用
- 04メディアクエリーの単位を案内
- 05文字拡大のレビュー項目を提供
活用シーン
- 01ユーザーのフォント設定に適応する画面設計
- 02固定サイズによるテキスト切れの確認
- 03CSS の単位やメディアクエリーのレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dembrandt/ dembrandt-skills --skill sizing-unitsインストール後、Claude Code で/sizing-unitsを入力して読み込まれたか確認します。
詳細
サイズ単位
単位が答える問い
単位は書式の好みではありません。ユーザーがテキストを拡大したときに値がどう変化するかを示すものです。
rem— この値はテキストに属し、テキストとともに大きくなります。px— この値は画面に属し、その場にとどまります。%、fr、ch、clamp()、min()— この値は利用可能なスペースに属します。
ハウススタイルを決めてどこにでも適用するのではなく、この問いに答えて単位を選びましょう。すべてを rem にする立場も、すべてを px にする立場も、どちらも不具合を生みますが、その不具合はそれぞれ異なります。
ズームはフォントサイズ設定とは別物です
どこでも px を使うべきだという一般的な主張は、ブラウザーにはすでにページ全体をズームする機能があるため、ルートのフォントサイズは無視してよいというものです。しかし、この2つは別々のユーザーに向けた、別々の操作です。
- ページ全体のズームはレイアウトも含め、すべてを拡大します。文字を大きくする代わりに、横スクロールが必要になり、画面に表示できる項目も減ります。
- ブラウザーのデフォルトフォントサイズはテキストを拡大し、レイアウトはそのままにします。これは、ロービジョンのユーザーが一度設定し、何年も変更しない設定です。プロダクトがその設定を無視したからといって、ズームに切り替えることはありません。
すべての寸法を px で固定したプロダクトは、前者のユーザーには応えますが、後者のユーザーをひそかに拒みます。WCAG 2.2 SC 1.4.4(テキストのサイズ変更)は、コンテンツや機能を損なわずにテキストを200%まで拡大できることを求め、SC 1.4.10(リフロー)は、ページが1列レイアウトで表示できることを求めています。[[wcag-accessibility]] を参照してください。
rem を使う対象
タイポグラフィ。 すべてのフォントサイズと行の高さです。[[modular-scale-typography]] を参照してください。
テキスト周りのパディング。 ボタン内部のパディングを px で指定すると、大きなテキストが端に押し付けられます。rem なら、囲んでいる語句に合わせて余白も拡大します。
コントロールの高さ。 24px のテキストを含む40pxのコントロールは壊れています。高さのトークンを rem で記述すれば、テキストサイズにかかわらず、コントロールらしい形を保てます。[[component-family-consistency]] を参照してください。
幅の基準。 テキスト列の max-width には 65ch または rem 値を使い、px は使いません。
テキストを含むブロック間の間隔。 フォームや記事のスタック間隔は、読むリズムの一部です。
px を使う対象
極細線とボーダー。 1px は意図的に1デバイスピクセルを表します。rem で指定すると、ルートサイズが大きいときに 1.25px となり、ぼやけた線として描画されます。
シャドウのオフセットとぼかし。 浮き上がりは画面上の効果です。[[elevation-and-depth]] を参照してください。
コントロール内の小さなアイコン。 アイコンがテキストではなく、固定されたグリフである場合に使います。
サブピクセル単位の調整。 2つのボーダーが二重になるのではなく、重なるようにする -1px などです。
相対単位を使う対象
レイアウトの幅と間隔です。「安定させるために px で固定する」という直感が誤るのはここです。px で固定したコンテナーは安定しているのではなく、壊れやすいのです。その中のテキストは拡大し続け、固定されたボックスこそが、拡大したテキストを切り取る原因になります。
/* Brittle — the box cannot absorb anything */
.card { width: 320px; height: 180px; }
.sidebar { width: 280px; }
/* Resilient */
.card { max-width: 20rem; min-height: 11.25rem; }
.sidebar { width: clamp(16rem, 22%, 22rem); }
テキストを含む要素には、height ではなく min-height を使います。 固定の高さは拡大できません。最小の高さなら、通常時は形を保ちながら、必要なときには広がります。
メディアクエリ
メディアクエリでは em を使います。メディアクエリ内の rem と em はどちらも、設定した html { font-size } を無視し、ブラウザーのデフォルトフォントサイズを基準に解決されます。そのため、正直な表記は em です。また、どちらも px のブレークポイントとは異なり、ユーザーの設定を尊重します。デフォルトフォントサイズが大きいユーザーには、デバイスの幅ではなく、実際のテキストサイズに応じたレイアウトが適用されます。
@media (min-width: 48em) { /* ~768px at default settings */ }
ルートサイズをリセットしない
html { font-size: 62.5%; } /* Do not do this */
62.5% の手法は、rem の計算を簡単にするためのものです。16px を 1.6rem として扱えます。暗算が楽になる代わりに、デフォルトでユーザーが明示した設定を上書きすることになります。ルートはブラウザーのデフォルトのままにし、計算はツールに任せましょう。
スクリプトでサイズを測定するコンテナは、測定対象のサイズに依存してはなりません
スクリプトがコンテナを基準に要素のサイズを測定する場合、すべてのブレークポイントで、コンテナのサイズが明確に定まり、かつその要素に依存しないようにする必要があります。コンテナが子要素に合わせて縮むと、測定値は子要素自身の縮小したサイズになり、サイズが明確に定まる親子間のつながりが失われるブレークポイントでは、要素は気づかないうちに縮んだままになります。測定対象のボックスまで、親子間のつながりを通じて明確なサイズを指定し、ウィンドウイベントではなく、ボックス自体を監視してください。
レビューチェックリスト
- すべてのフォントサイズ、行の高さ、テキスト周辺のパディングは rem で指定されていますか?
- ボーダー、ヘアライン、シャドウのオフセットは px で指定されていますか?
- テキストを含む要素で、
min-heightではなくheightを使用しているものはありませんか? - コンテナの幅は固定 px ではなく、相対値(
%、fr、clamp()、max-width)で指定されていますか? - メディアクエリのブレークポイントは
emで指定されていますか? -
html { font-size }はブラウザーのデフォルトのままですか? - ブラウザーのフォントサイズを 200% に設定した場合でも、すべてのコントロールにラベルが収まり、切り取りもページの横スクロールも発生しませんか?
- スクリプトでサイズを測定するコンテナはすべて、サイズを決める子要素ではなく、レイアウトによってサイズが決まっていますか?