zudo-css-wisdom
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

clamp()を使った流体フォントサイズ

問題

レスポンシブタイポグラフィは、従来、異なるブレークポイントでフォントサイズを調整するために複数のメディアクエリを必要としていました。これはサイズ間の急激な変化を生み、冗長でメンテナンスしにくいCSSになります。AIエージェントは、流体スケーリングの代わりに、任意のブレークポイントで固定のpxrem値を生成しがちで、モバイルではテキストが小さすぎ、デスクトップでは大きすぎ、ブレークポイント間の遷移が不自然になります。

解決方法

CSSのclamp()関数を使えば、1行でフォントサイズをビューポート幅に応じて最小値と最大値の間で滑らかにスケーリングできます。構文はclamp(min, preferred, max)で、preferred値には通常、remベースとvwコンポーネントを組み合わせてビューポート相対のスケーリングを実現します。

計算式

clamp()のpreferred(中間)値は、ビューポート幅の一次関数として計算します。一般的な式は次のとおりです:

preferred = base-rem + (slope × 1vw)

slopeは、目標のフォントサイズ範囲とビューポート範囲から算出します:

slope = (max-size - min-size) / (max-viewport - min-viewport)

コード例

基本的な流体タイポグラフィ

/* 本文テキスト: 320px〜1200pxのビューポートで16px〜20pxにスケール */
body {
  font-size: clamp(1rem, 0.909rem + 0.45vw, 1.25rem);
}

/* h1: 28px〜48pxにスケール */
h1 {
  font-size: clamp(1.75rem, 1.295rem + 2.27vw, 3rem);
}

/* h2: 24px〜36pxにスケール */
h2 {
  font-size: clamp(1.5rem, 1.227rem + 1.36vw, 2.25rem);
}

/* h3: 20px〜28pxにスケール */
h3 {
  font-size: clamp(1.25rem, 1.068rem + 0.91vw, 1.75rem);
}

流体タイプスケールシステム

:root {
  /* ビューポート範囲: 320px〜1200px */
  --step--1: clamp(0.833rem, 0.787rem + 0.23vw, 1rem);
  --step-0: clamp(1rem, 0.909rem + 0.45vw, 1.25rem);
  --step-1: clamp(1.2rem, 1.042rem + 0.79vw, 1.563rem);
  --step-2: clamp(1.44rem, 1.186rem + 1.27vw, 1.953rem);
  --step-3: clamp(1.728rem, 1.339rem + 1.95vw, 2.441rem);
  --step-4: clamp(2.074rem, 1.494rem + 2.9vw, 3.052rem);
}

body {
  font-size: var(--step-0);
}

h1 {
  font-size: var(--step-4);
}

h2 {
  font-size: var(--step-3);
}

h3 {
  font-size: var(--step-2);
}

small {
  font-size: var(--step--1);
}
clamp()による流体タイポグラフィ — ビューポートをリサイズしてスケーリングを確認

コンテナクエリとの併用

コンテナクエリ単位(cqicqwなど)を使うと、ビューポートの代わりにコンテナのサイズを基準に同じclamp()パターンを適用できます。単位の全リストはコンテナクエリの単位を参照してください。

/* ビューポートではなくコンテナ幅に対する流体サイズ */

/* 加算型: remベース + cqi項 */
.card-title {
  font-size: clamp(1rem, 0.5rem + 3cqi, 1.5rem);
}

/* 純粋型: cqiのみ、remベースなし */
.card-title {
  font-size: clamp(1rem, 5cqi, 2rem);
}
パターン使いどころ
加算型clamp(1rem, 0.5rem + 3cqi, 1.5rem)remベースがコンテナ幅に依存しないサイズの下限になる — ほぼ0幅のコンテナでもテキストが緩やかに縮小する。どんなコンテナサイズでも可読性を保つべき見出しに使う。
純粋型clamp(1rem, 5cqi, 2rem)フォントサイズはコンテナのインラインサイズに正比例する(5cqiはその5%)。他のCSSですでにコンテナの幅に厳密な最小・最大値がある場合に使い、緩やかな縮小ではなくコンテナの実際のレンダリングサイズにテキストを追従させたいときに適する。

固定コンポジションのステージ(スライド、デッキビューア、固定アスペクトの埋め込み)では、純粋型は選択肢のひとつではなく正しい契約です — 均一な可読性フロアの導出方法とズームのトレードオフの扱いも含めて、ステージ比例タイポグラフィを参照してください。

これらの単発の値をコンポーネントスコープのタイポグラフィ・スペーシングトークンスケールへと昇格させる方法と、そのスケールを機能させ続ける3つのルール(テキストズームのアクセシビリティのためのrem優位のclamp、コンテナスコープでの使用、固定pxのヘアライン)については、トークンスケールとしてのコンテナクエリ単位を参照してください。

AIがよくやるミス

  • clamp()の代わりにメディアクエリのブレークポイントで固定のpxrem値を使い、サイズの急激な変化を引き起こす

  • preferred値でremコンポーネントを省略し(vwのみ使用)、ズームやアクセシビリティが壊れる

  • 最小値を小さくしすぎる(本文テキストで1rem/16px未満)と、モバイルでテキストが読めなくなる

  • 極端なビューポート幅で計算式をテストせず、ウルトラワイドモニターで文字が異常に大きくなる

  • 上限・下限のないcalc()vwだけの組み合わせ(例: calc(1rem + 1vw))を使う — clamp()なら自然に上下限が設定される

  • すべてのテキスト要素に流体サイズを適用する — 本文テキストは固定の1remで十分な場合が多い。流体サイズが効果的なのは見出しやディスプレイテキストのみ

  • ビューポートブレークポイント方式からコンテナクエリ方式への移行時、そのブレークポイント値がそもそも適切なサイズだったかを確認せず、旧ブレークポイントのフォントサイズからcqi係数を単純に逆算する — 計算式はコンテナ幅に対して数学的に連続していても、デザインが意図した見た目とは視覚的にズレて見える場合がある

使い分け

  • モバイルとデスクトップ間でスケールが必要な見出しやディスプレイテキスト

  • すべてのステップが流体的に調整されるべきタイプスケールシステム

  • 小さな画面で縮小が必要な大きなテキストのヒーローセクション

  • ブレークポイントベースのフォントサイズ変更で目に見える段差が生じるあらゆるケース

clamp()の使用を避けるべき場面:

  • すべてのサイズで1remで十分な本文テキスト

  • 固定寸法のコンポーネント内のテキスト

  • 特定のブレークポイントでの精密な制御が必要な場面

参考リンク

Revision History

作成更新