
CSSのclamp()関数とは
clamp()関数はCSSで値に最小値と最大値を設定し、適応的な変化を実現できる便利な関数です。
主にCSSのフォントサイズで用いられ、レスポンシブデザインに役立ちます。
例えば、以下のclamp(1rem, 2vw, 2rem)の場合は…
- 最小フォントサイズが1rem (16px)
- 推奨値が2vw
- 最大フォントサイズが2rem (32px)
.example {
font-size: clamp(1rem, 2vw, 2rem);
}
2vwが使用されている場合は…
- ビューポートの幅が400pxの場合は 400px * 0.02 = 8px
- ビューポートの幅が800pxの場合は 800px * 0.02 = 16px
- ビューポートの幅が1600pxの場合は 1600px * 0.02 = 32px
…という結果になります。
最小フォントサイズが1rem (16px)なので、幅が800px未満になってもフォントサイズが16px未満にはなりません。
最大フォントサイズは2rem (32px)なので、幅が1600px以上のフォントサイズは常に32pxになります。
※ clampのフォントサイズにremを使用していますが、今回のサンプルの場合はルートフォントサイズがデフォルト(16px)なので、clamp(16px, 2vw, 32px) と書いても結果は同じです。
CSS font-size: clamp(1rem, 2vw, 2rem); のサンプル
font-size変動関数の作成方法
前述の条件の場合はclamp()で簡単に作成できますが、例えば…
- 最小フォントサイズが0.75rem (12px)
- ビューポートの最小値が360px
- ビューポートの最大値が1600px
- 最大フォントサイズが1.5rem (24px)
…以上の条件の場合は、以下のようにclamp()の引数の値が複雑でフォントサイズが不明瞭になります。
.example {
font-size: clamp(0.75rem, 0.532rem + 0.968vw, 1.5rem);
}
ビューポートも0.532rem + 0.968vwでは最小値と最大値がまったくわかりません😅
そんなときは、以下のようにSCSS (Sass) を使用してclampの結果を返す関数を作成しておけば、簡単にレスポンシブデザイン用のfont-size変動関数を作成できます。
@function round-3-decimals($value) {
@return calc(round($value * 1000) / 1000);
}
@function responsive-font-size(
$mobile-size, // スマホ用フォントサイズ(px)
$desktop-size, // デスクトップ用フォントサイズ(px)
$min-vw: 360px, // 最小ビューポート幅(px)
$max-vw: 1600px, // 最大ビューポート幅(px)
$base-size: 16px, // ベースフォントサイズ(px)
) {
// フォントサイズの変化率を計算
$slope: calc(($desktop-size - $mobile-size) / ($max-vw - $min-vw));
$intercept: $mobile-size - $slope * $min-vw;
// clamp関数でフォントサイズを設定
@return clamp(
#{round-3-decimals(calc($mobile-size / $base-size))}rem,
#{round-3-decimals(calc($intercept / $base-size))}rem + #{round-3-decimals($slope * 100)}vw,
#{round-3-decimals(calc($desktop-size / $base-size))}rem
);
}
.example {
font-size: responsive-font-size(12px, 24px);
}
// 結果
// .example {
// font-size: clamp(0.75rem, 0.532rem + 0.968vw, 1.5rem);
// }
このresponsiveFontSize関数をSassのPlaygroundで試すと、正しく変換されていることが確認できます。
Min-Max-Value InterpolationやVS Code拡張機能のClamp It!を使用されている方が多いと思いますが、responsiveFontSize関数を使用したやり方のほうが、コードがシンプルでわかりやすくなるので、こちらを使用することをオススメします。