1. ホーム
  2. CSS

【CSS】min()・max()・clamp() の使い方|レスポンシブなサイズ指定を関数で実現する

Share

「スマホでは小さく、PCでは大きく」といったサイズ指定を、メディアクエリを何個も書かずに実現できるのが CSS の min() / max() / clamp() です。幅・余白・文字サイズなどを「最小〜最大の範囲で画面幅に追従させる」書き方ができ、レスポンシブ対応がぐっと楽になります。この記事では3つの関数の違いと使い分け、よく使うパターンを動くデモつきで解説します。

min() / max() / clamp() でできること

これらは CSS の「数学関数」と呼ばれるもので、複数の値を比べてどれを採用するかを計算してくれます。px%vw(ビューポート幅の1%)など、単位の違う値どうしを混ぜて比較できるのが大きな特徴です。これにより、これまでメディアクエリで段階的に切り替えていたサイズを、1行でなめらかに変化させられます。

それぞれの役割
min(A, B)        /* A と B の小さい方を採用 → 上限を作る */
max(A, B)        /* A と B の大きい方を採用 → 下限を作る */
clamp(MIN, VAL, MAX)  /* VAL を MIN〜MAX の範囲に収める */

名前から「最小値・最大値を指定する」と思いがちですが、効果は逆になることが多いので注意してください。min() は「小さい方を選ぶ」ので結果として上限を、max() は「大きい方を選ぶ」ので結果として下限を作ります。ここを押さえると一気に使いこなせます。

min() で「大きくなりすぎ」を防ぐ

min() は渡した値のうち小さい方を採用します。たとえば幅を min(90%, 600px) にすると、画面が広いときは 600px で止まり、狭いときは 90% に縮みます。「基本は親要素に合わせたいが、広い画面では広がりすぎないようにしたい」という、コンテンツの最大幅指定でよく使うパターンです。

style.css
.container {
  /* 90% と 600px の小さい方 → 最大でも 600px に収まる */
  width: min(90%, 600px);
  margin: 0 auto;
}

max-width: 600px; width: 90%; と2行で書いていたものを、1行にまとめられるイメージです。

max() で「小さくなりすぎ」を防ぐ

逆に max() は大きい方を採用するので、下限を作りたいときに使います。たとえば余白を max(16px, 3vw) にすると、画面が狭くても最低 16px は確保され、広い画面では 3vw に広がります。タップ領域の確保や、最低限の余白を守りたいときに便利です。

style.css
.section {
  /* 16px と 3vw の大きい方 → 最低でも 16px は確保 */
  padding: max(16px, 3vw);
}

clamp() で「最小・基準・最大」をまとめて指定する

実務でいちばん出番が多いのが clamp() です。clamp(最小値, 基準値, 最大値) の3つを渡すと、基準値を最小値と最大値の範囲に収めてくれます。基準値に vw のような可変の単位を使うと、画面幅に応じてなめらかに変化しつつ、小さすぎ・大きすぎを防げます。

とくにレスポンシブな文字サイズ(フルードタイポグラフィ)と相性が抜群です。次のように書くだけで、スマホでは 1.25rem、PCでは 2.25rem まで、その間は画面幅に追従して変化します。

style.css
.title {
  /* 最小1.25rem、基準5vw、最大2.25rem */
  font-size: clamp(1.25rem, 5vw, 2.25rem);
}

下のデモは clamp() をカードの幅・余白・文字サイズに使った例です。プレビュー枠の幅を広げたり狭めたりすると、各サイズがなめらかに変化するのが分かります。

<div class="card">
  <h2 class="title">clamp() でサイズを自動調整</h2>
  <p class="text">画面の幅に合わせて、文字サイズ・余白・カード幅がなめらかに変化します。プレビュー枠の幅を変えて確認してみてください。</p>
</div>
.card {
  /* 最小280px・基本は親の90%・最大520px の範囲で伸縮 */
  width: clamp(280px, 90%, 520px);
  margin: 24px auto;
  /* 余白も画面幅に応じて 16px〜40px で変化 */
  padding: clamp(16px, 5vw, 40px);
  border: 2px solid #007bff;
  border-radius: 12px;
  box-sizing: border-box;
}

.title {
  /* 最小1.25rem〜最大2.25rem。間は 5vw で追従 */
  font-size: clamp(1.25rem, 5vw, 2.25rem);
  color: #007bff;
  margin: 0 0 12px;
}

.text {
  font-size: clamp(0.9rem, 2.5vw, 1.1rem);
  line-height: 1.7;
  margin: 0;
}
Preview

計算式や入れ子も使える

3つの関数の中では、calc() のような四則演算をそのまま書けます(calc() で囲む必要はありません)。たとえば clamp(1rem, 0.5rem + 2vw, 2rem) のように、基準値に「固定分+可変分」を組み合わせると、変化のカーブをより細かく調整できます。

style.css
.box {
  /* 基準値に計算式を直接書ける */
  width: clamp(300px, 50% + 100px, 800px);
  /* min()/max() を入れ子にすることも可能 */
  padding: max(12px, min(2vw, 32px));
}

3つの関数の使い分け

どれを使えばいいか迷ったときは、次の対応で考えると整理しやすいです。

関数効果使いどころ
min(A, B)上限を作る(大きくなりすぎを防ぐ)コンテンツの最大幅
max(A, B)下限を作る(小さくなりすぎを防ぐ)最低限の余白・サイズ確保
clamp(MIN, VAL, MAX)上限と下限の両方を作るレスポンシブな文字・幅・余白

なお clamp(MIN, VAL, MAX)max(MIN, min(VAL, MAX)) と同じ意味です。clamp() がいちばん汎用的なので、まずは clamp() から覚えるのがおすすめです。

サイズが思った通りに変わらないとき

最小値と最大値の大小が逆になっている

clamp() は最小値が最大値より大きいと、最小値が優先されます。clamp(2rem, 5vw, 1rem) のように最小と最大を逆に書くと、常に 2rem になってしまい「変化しない」と感じる原因になります。第1引数が必ず第3引数より小さくなるよう確認してください。

vw を使ったのに変化しない

基準値に固定値(pxrem だけ)を使っていると、画面幅を変えても値が変わりません。なめらかに変化させたいときは、基準値に vw% といった可変の単位を必ず含めましょう。逆に、基準値を固定にすれば「ある幅まではこのサイズ、それを超えたら別のサイズ」という段階的な上限・下限としても使えます。

アクセシビリティへの配慮

文字サイズを vw だけで決めると、ブラウザのズーム(拡大)が効きにくくなることがあります。clamp(1rem, 2.5vw, 1.4rem) のように rem を混ぜておくと、ユーザーが文字を拡大したときにも追従しやすくなり、読みやすさを保てます。

まとめ

min() / max() / clamp() を使うと、メディアクエリを増やさずにレスポンシブなサイズ指定ができます。ポイントを振り返ります。

  • min() は小さい方を選び「上限」を作る
  • max() は大きい方を選び「下限」を作る
  • clamp(最小, 基準, 最大) は上限と下限の両方を一度に指定でき、いちばん使いやすい
  • 基準値に vw% を含めると画面幅になめらかに追従する

まずは見出しの文字サイズや、コンテンツの最大幅から clamp() を取り入れてみると効果を実感しやすいはずです。各関数の詳しい仕様は MDN の clamp() リファレンス も参考にしてください。