メインコンテンツまでスキップ
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

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()による流体タイポグラフィ — ビューポートをリサイズしてスケーリングを確認

コンテナクエリとの併用

/* ビューポートではなくコンテナ幅に対する流体サイズ */
.card-title {
font-size: clamp(1rem, 0.5rem + 3cqi, 1.5rem);
}

AIがよくやるミス

  • clamp()の代わりにメディアクエリのブレークポイントで固定のpxrem値を使い、サイズの急激な変化を引き起こす
  • preferred値でremコンポーネントを省略し(vwのみ使用)、ズームやアクセシビリティが壊れる
  • 最小値を小さくしすぎる(本文テキストで1rem/16px未満)と、モバイルでテキストが読めなくなる
  • 極端なビューポート幅で計算式をテストせず、ウルトラワイドモニターで文字が異常に大きくなる
  • 上限・下限のないcalc()vwだけの組み合わせ(例: calc(1rem + 1vw))を使う — clamp()なら自然に上下限が設定される
  • すべてのテキスト要素に流体サイズを適用する — 本文テキストは固定の1remで十分な場合が多い。流体サイズが効果的なのは見出しやディスプレイテキストのみ

使い分け

  • モバイルとデスクトップ間でスケールが必要な見出しやディスプレイテキスト
  • すべてのステップが流体的に調整されるべきタイプスケールシステム
  • 小さな画面で縮小が必要な大きなテキストのヒーローセクション
  • ブレークポイントベースのフォントサイズ変更で目に見える段差が生じるあらゆるケース

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

  • すべてのサイズで1remで十分な本文テキスト
  • 固定寸法のコンポーネント内のテキスト
  • 特定のブレークポイントでの精密な制御が必要な場面

参考リンク