SCSSのclamp()関数を使ったfont-size変動関数の作成方法

CSSのclamp()関数とは

clamp()関数はCSSで値に最小値と最大値を設定し、適応的な変化を実現できる便利な関数です。

主にCSSのフォントサイズで用いられ、レスポンシブデザインに役立ちます。

例えば、以下のclamp(1rem, 2vw, 2rem)の場合は…

  • 最小フォントサイズが1rem (16px)
  • 推奨値が2vw
  • 最大フォントサイズが2rem (32px)
CSS
.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()の引数の値が複雑でフォントサイズが不明瞭になります。

CSS
.example {
  font-size: clamp(0.75rem, 0.532rem + 0.968vw, 1.5rem);
}

ビューポートも0.532rem + 0.968vwでは最小値と最大値がまったくわかりません😅

そんなときは、以下のようにSCSS (Sass) を使用してclampの結果を返す関数を作成しておけば、簡単にレスポンシブデザイン用のfont-size変動関数を作成できます。

SCSS
@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関数を使用したやり方のほうが、コードがシンプルでわかりやすくなるので、こちらを使用することをオススメします。

カテゴリーcss