CSSでフォントサイズの最大値・最小値を指定する方法|clamp(), min(), max()完全解説

WEBデザイナーのイメージ

レスポンシブなサイトを作っていると、「スマホだと文字が小さすぎる」「大画面だと文字が間延びして見える」という悩みにぶつかります。かといって画面幅ごとにメディアクエリを積み上げると、CSSはあっという間に読みづらくなります。

私自身、以前はブレークポイントごとに font-size を書き分けていましたが、今は clamp() をはじめとするCSS関数で解決するのが定番になりました。

CSSには max-font-sizemin-font-size のようなプロパティは存在しません。そのかわりに使えるのが、clamp() / min() / max() 関数です。これらを使うと、画面サイズに応じて文字を滑らかに変化させつつ、小さくなりすぎ・大きくなりすぎを防げます。

この記事では、次のポイントを実例つきで整理します。

  • レスポンシブフォント設計の基本
  • clamp()関数の仕組みと使い方
  • min() / max()関数の役割と使い分け
  • remとvwを組み合わせたFluid Typography
  • ズームを妨げないアクセシビリティ配慮

レスポンシブフォントサイズ設計の基本

フォントサイズを固定値だけで指定すると、デバイスによって読みやすさが大きく変わってしまいます。よくあるのが次のような悩みです。

  • スマートフォンでは文字が小さすぎる
  • 大型ディスプレイでは文字が大きすぎる
  • メディアクエリが増えてCSSが複雑になる

従来は、画面幅ごとにメディアクエリでフォントサイズを切り替えるのが一般的でした。

p {
  font-size: 16px;
}

@media (min-width: 768px) {
  p {
    font-size: 18px;
  }
}

@media (min-width: 1200px) {
  p {
    font-size: 20px;
  }
}

これでも動きますが、ブレークポイントが増えるほど記述が膨らみ、変化も段階的でカクカクします。

そこで近年よく使われるのが Fluid Typography(流動的タイポグラフィ)という考え方です。画面サイズに応じてフォントサイズを滑らかに変化させる設計で、その中心になるのが clamp() です。

clamp()関数でフォントサイズを制御する

clamp()は、フォントサイズの「最小値・推奨値・最大値」を一度に指定できる関数です。

基本構文

font-size: clamp(最小値, 推奨値, 最大値);

基本例

p {
  font-size: clamp(16px, 2vw, 24px);
}

この設定では、フォントサイズが次のように振る舞います。

  • 画面が狭い → 16pxより小さくならない
  • 画面が広い → 24pxより大きくならない
  • その間は2vw(ビューポート幅の2%)を基準に変化する

MDNの定義によると、clamp(MIN, VAL, MAX)max(MIN, min(VAL, MAX)) として解決されます。つまり推奨値が最小値を下回れば最小値に、最大値を上回れば最大値に丸められ、それ以外はそのまま使われるという仕組みです。

clamp()を使うメリット

  • 最小値と最大値を同時に制御できる
  • メディアクエリを減らせる
  • フォントサイズが滑らかに変化する
  • CSSがシンプルになる

こうした理由から、今のレスポンシブデザインではフォントサイズ調整の基本はclamp()と言えます。

min()関数でフォントサイズの上限を制御する

min()関数は、カンマ区切りで並べた値のうち「小さい方」を採用する関数です。

基本構文

font-size: min(値1, 値2);

使用例

p {
  font-size: min(2vw, 20px);
}

この場合、画面が狭いうちは2vwが小さいのでそちらが採用され、画面が広がって2vwが20pxを超えると20pxが採用されます。結果としてフォントサイズが20pxを超えることはありません。

つまりmin()はフォントサイズの上限を決めたいときに使います。

max()関数でフォントサイズの下限を制御する

max()関数は、並べた値のうち「大きい方」を採用する関数です。

基本構文

font-size: max(値1, 値2);

使用例

p {
  font-size: max(1vw, 12px);
}

この設定では、画面が狭くて1vwが12pxを下回るときは12pxが採用され、画面が広がれば1vwが採用されます。つまりフォントサイズが12pxより小さくなりません。

max()はフォントサイズの下限を保証したいときに使います。

clamp()とmin()/max()の関係

前述のとおり、clamp()はmin()とmax()を組み合わせたものと同じ動作をします。例えば次のコードは、

font-size: clamp(16px, 2vw, 24px);

MDNの定義に沿うと、次のコードと同じ意味になります。

font-size: max(16px, min(2vw, 24px));

書けば同じ結果になりますが、意図が一目で伝わる分、フォントサイズの上下限を扱う場面ではclamp()の方が読みやすくおすすめです。

remとvwを組み合わせたFluid Typography

単純に 2vw だけを使うと、画面幅によってはフォントの変化が大きすぎることがあります。そこで実務でよく使われるのが、remとvwを組み合わせた書き方です。

font-size: clamp(16px, 1rem + 0.5vw, 24px);

clamp()やmin()、max()の内側では、calc()で囲まなくても足し算・引き算・掛け算・割り算がそのまま書けます(+- の前後には半角スペースが必要です)。この書き方には次のメリットがあります。

  • remで基本サイズを安定させられる
  • vwで画面幅に応じた変化を加えられる
  • clamp()で上下限を制御できる

remを土台に据えることで、後述するズーム対応の面でも扱いやすくなります。海外のCSS設計でも定番のFluid Typographyパターンです。

vwだけに頼らない、ズーム対応のアクセシビリティ

便利なvwですが、フォントサイズをvwだけで指定するのは避けたいポイントがあります。ビューポート単位はブラウザの拡大(ズーム)やユーザーのフォント設定に追従しにくく、200%まで拡大しても文字がほとんど大きくならないことがあるためです。

WCAG 1.4.4(テキストのサイズ変更)では、支援技術なしで文字を200%まで拡大できることが求められています。これを満たすには、次の点を意識します。

  • vw単体ではなく、remを併用する(例:1rem + 0.5vw
  • clamp()の最大値を最小値の2倍程度まで確保し、拡大の余地を残す

例えば次のように、上下限をremで持たせておくと拡大に追従しやすくなります。

h1 {
  font-size: clamp(1.8rem, 2.5vw, 2.8rem);
}

「滑らかに変化するか」だけでなく「ちゃんと拡大できるか」まで確認しておくと安心です。

clamp()の計算方法(プロ向け)

実務では、vwを勘で決めるのではなく、デザイン幅から逆算してclampを組むこともあります。例えば次の条件を考えます。

  • 最小画面幅:320px
  • 最大画面幅:1200px
  • 最小フォント:16px
  • 最大フォント:24px

フォントの差は8px、画面幅の差は880pxです。これを使うと、推奨値は次のように表せます。

font-size: clamp(16px, calc(16px + 8 * ((100vw - 320px) / 880)), 24px);

この式なら、320pxで16px、1200pxで24pxとなり、その間を直線的に変化します。デザインカンプ通りのレスポンシブフォントを再現したいときに便利です。

フォントスケール設計

レスポンシブタイポグラフィでは、フォントサイズを個別に調整するより、用途ごとのスケールを決めておく方が管理しやすくなります。例えば次のような設計です。

用途 フォントサイズ
本文 clamp(16px, 1rem + 0.4vw, 18px)
小見出し clamp(20px, 1.2rem + 0.6vw, 28px)
見出し clamp(28px, 2rem + 1vw, 48px)

このようにスケールを先に決めておくと、サイト全体のタイポグラフィに統一感が出ます。

clamp(), min(), max()の使い分け

関数 用途
clamp() レスポンシブフォントの基本
min() 上限(大きくなりすぎ)の制御
max() 下限(小さくなりすぎ)の保証

Web制作の現場では、おおむね次のように使い分けられます。

  • フォントサイズ調整 → clamp()
  • レイアウトの幅や余白の制御 → min() / max()

まとめ

フォントサイズを固定値だけで管理すると、デバイスごとに読みやすさが変わってしまいます。そこで役立つのがCSSの clamp() / min() / max() 関数です。

特にclamp()を使えば、

  • フォントサイズの最小値を保証できる
  • 最大値を制限できる
  • 画面サイズに応じて滑らかに変化させられる

という、理想的なレスポンシブタイポグラフィが実現できます。そのうえで、vwだけに頼らずremを併用し、拡大できる余地を残しておけば、アクセシビリティ面でも安心です。

文字の読みやすさは、サイトの使い勝手やデザインの印象を大きく左右します。今回のCSS関数を土台に、快適なレスポンシブタイポグラフィを組んでみてください。