CSS関数のclamp()・max()・min()についてまとめてみる

Blog

こんにちは。4回目の登場です。エンジニアのuchimuroです。

存在は知っているけれども実はまだ使用したことのないCSSのプロパティや関数って結構あるんですよね…。

そんな中でも今まで食わず嫌いしていたCSS関数のclamp()・max()・min()をそろそろ実案件でも使ってみようと思っているので、今回はそれらについてまとめてみようと思います。

clamp()

clamp()関数には最小値、推奨値、最大値の3つの値を設定することができ、その中で条件に合致する1つの値が適用されます。

  • 推奨値:最小値と最大値の間である限り推奨値が適用されます。
  • 最小値:許容される最も小さい値で、推奨値がこの値よりも小さくなる場合は最小値が適用されます。
  • 最大値:許容される最も大きな値で、推奨値がこの値よりも大きくなる場合は最大値が適用されます。
// プロパティ: clamp(最小値, 推奨値, 最大値);
width: clamp(60px, 10vw, 240px);

慣れてしまえば問題なく使いこなせそうですが、使い始めたばかりだと、どの条件でどの値が適用されるのかわかりづらいですよね…。
ですので上記の記述を元に100vwに実際の大きさを指定して、値がどのように変化するのか見ていきたいと思います。

100vw = 1200pxの場合

100vw = 1200pxの場合は推奨値である10vwは120pxになります。
この場合は最小値と最大値のどちらにも引っかかっていないので、下記を値に設定しているのと同義となります。

width: 10vw; // 120px

100vw = 500pxの場合

100vw = 500pxの場合は推奨値である10vwは50pxになります。
ということは最小値に設定した60pxを下回ってしまいます。
最小値よりも値が小さくなることはないので、この場合は下記を値に設定しているのと同義となります。

width: 60px;

100vw = 3000pxの場合

100vw = 3000pxの場合は推奨値である10vwは300pxになります。
ということは最大値に設定した240pxを上回ってしまいます。
最大値よりも値が大きくなることはないので、この場合は下記を値に設定しているのと同義となります。

width: 240px;

width: clamp(60px, 10vw, 240px);の記述を要約すると…

  • 100vwが600px〜2400px(10vwが60px〜240px)の場合は推奨値が適用されます。
  • 100vwが600pxより小さい(10vwが60pxより小さい)場合は最小値が適用されます。
  • 100vwが2400pxより大きい(10vwが240pxより大きい)場合は最大値が適用されます。

max()

max()関数には1つ以上の値を設定することができ、その中で最大の値1つが適用されます。
つまり最小値を定義することができます。
(関数名はmax()なのに定義しているのが最小値なのはややこしいポイントですね…。)

// プロパティ: max(値1, 値2, ……);
width: max(10vw, 240px);

今回もclamp()関数の時と同様に上記の記述を元に100vwに実際の大きさを指定して、値がどのように変化するのか見ていきたいと思います。

100vw = 2000pxの場合

100vw = 2000pxの場合は値1に設定した10vwは200pxになります。
値2に設定した240pxと比較すると値2の方が大きいので、この場合は下記を値に設定しているのと同義となります。

width: 240px;

100vw = 3000pxの場合

100vw = 3000pxの場合は値1に設定した10vwは300pxになります。
値2に設定した240pxと比較すると値1の方が大きいので、この場合は下記を値に設定しているのと同義となります。

width: 10vw; // 300px

width: max(10vw, 240px);の記述を要約すると…

  • 100vwが2400pxより大きい(10vwが240pxより大きい)場合は値1(10vw)が適用されます。
  • 100vwが2400px以下(10vwが240px以下)の場合は値2(240px)が適用されます。

min()

min()関数には1つ以上の値を設定することができ、その中で最小の値1つが適用されます。
つまり最大値を定義することができます。
(max()と同様に関数名はmin()なのに定義しているのが最大値なのはややこしいポイントです…。)

// プロパティ: min(値1, 値2, ……);
width: min(10vw, 60px);

それでは今回も上記の記述を元に100vwに実際の大きさを指定して、値がどのように変化するのか見ていきたいと思います。

100vw = 1000pxの場合

100vw = 1000pxの場合は値1に設定した10vwは100pxになります。
値2に設定した60pxと比較すると値2の方が小さいので、この場合は下記を値に設定しているのと同義となります。

width: 60px;

100vw = 500pxの場合

100vw = 500pxの場合は値1に設定した10vwは50pxになります。
値2に設定した60pxと比較すると値1の方が小さいので、この場合は下記を値に設定しているのと同義となります。

width: 10vw; // 50px

width: min(10vw, 60px);の記述を要約すると…

  • 100vwが600pxより小さい(10vwが60pxより小さい)場合は値1(10vw)が適用されます。
  • 100vwが600px以上(10vwが60px以上)の場合は値2(60px)が適用されます。

使用例

上記の解説でclamp()・max()・min()の使用方法は一通り理解できたでしょうか…?
せっかくなので実際に役立ちそうな使用例もいくつか挙げてみたいと思います。

clamp()

可変するfont-sizeに最小値と最大値を設定する

.hoge {
    font-size: clamp(14px, 3vw, 40px);
}

画面幅に対してfont-sizeが比率を保ったまま可変するテキストにおいて、メディアクエリを使用しなくても極端な拡大と縮小を防ぐことができます。

max()

width + min-widthをまとめる

// width + min-widthを使用した記述
.hoge {
    width: 50%;
    min-width: 600px;
}

// width + max()関数を使用した記述
.hoge {
    width: max(50%, 600px);
}

width + min-widthの記述を1行にまとめることができます。

可変するpadding-topに最小値を設定する

.hoge {
    padding-top: max(4vw, 20px);
}

画面幅に対して比率を保ったままpadding-topが動的に可変しますが、20px以上の大きさは担保されるので、余白が狭くなりすぎる現象を防ぐことができます。

min()

width + max-widthをまとめる

// width + max-widthを使用した記述
.hoge {
    width: 50%;
    max-width: 1200px;
}

// width + min()関数を使用した記述
.hoge {
    width: min(50%, 1200px);
}

上記のmax()関数の例と同様にwidth + max-widthの記述を1行にまとめることができます。

可変するborder-bottomに最大値を設定する

.hoge {
    border-bottom: min(1vw, 6px) solid #000;
}

画面幅に対して比率を保ったままborder-bottomが動的に可変しますが、6pxよりは大きくならないので、線が太くなりすぎる現象を防ぐことができます。

おまけ

余談ではありますが、この2つの関数部分は同じ条件下ではどちらも同じ値が適用されます。
自分がやったようにvwに実際の大きさを指定して試してみてください。

width: clamp(60px, 10vw, 240px);
width: max(60px, min(10vw, 240px));

おわりに

しっかりと使い方を理解すれば、メディアクエリを多用しないコーディングができるようになるので、コードの記述量を減らすことができそうですね。

2021年10月現在、IE11では非対応となっていますが、2022年6月でサポートが切れる関係で対象ブラウザの範囲外とする案件も徐々に増えてきていると思いますので、今まで使用機会のなかった人もこのタイミングで是非使ってみてください!

それでは今回はここらへんで失礼します。

参考