Web制作実務役立ち

clamp()を使ってフォントサイズはレスポンシブで自動調整せよ【ジェネレーターとSass関数の使いかたも】

clamp()を使ってフォントサイズはレスポンシブで自動調整せよ【計算ツールとSass関数の使いかた】
本ページにはプロモーションが含まれています。

レスポンシブでフォントサイズ要素のサイズを変える時に、毎回メディアクエリで、画面幅毎にこんな指定をしていませんか?

@media screen and (max-width:768px) {
    .title {
        font-size: 14px;
}
@media screen and (min-width:768px) and (max-width:1024px) {
    .title {
        font-size: 24px;
}
@media screen and (min-width:1024px) {
    .title {
        font-size: 32px;
}

実は、今回紹介するclamp()を使用すれば、こんな煩わしい指定を毎回しなくても、一行で実装できます!

.title {
  font-size: clamp(0.875rem, -2.5rem + 7.03vw, 2rem);
}

この記事ではclamp()を実際に利用する際に必須となるジェネレーターの使い方や、scss関数の組み方も解説するので、

是非この記事を通してclamp()を今日から利用していってもらえればと思います。

Sassを使わない人はジェネレーターを使って、Sassを使う人は関数でラクラクclamp()でレスポンシブを管理できるようになります。

しょーご

この記事を書いたのは
しょーご@samurabrass

このブログ「しょーごログ」の運営者。2018年からエンジニアとしてサイト制作やシステム開発を行いつつ、ブログとYouTubeで情報発信を行っている。駆け出しエンジニアのコーディング課題添削も行う。

\現役エンジニアのレビュー付き/

実践レベルのコーディング課題公開中

デザインカンプからのコーディング練習課題【オリジナルポートフォリオを準備できるようになりました】
販売ページはこちら
  • デザインカンプからのコーディングを経験したい
  • 現役エンジニアのレビューを受けてみたい
  • 即戦力級のポートフォリオを用意したい

2024年にデザインを完全リニューアルしています!

コーディングを学習中の方はぜひご活用ください。

無料の入門編から本格企業サイトまで/

また、超実践編という鬼のようなコースもあるので、ほぼ実案件と同じ厳しい環境でコミュニケーション面までレビュー受けたい方がいれば、是非。

コーディング課題 超実践編

超実践編をとりあえず見てみる

clamp()の対応ブラウザ

一応caniuseで確認した所、モダンブラウザでは問題なく使えます。IEを切っている現場が多いと思うので、ほぼ前線に出しても問題無い関数と言えます。

https://caniuse.com/?search=clamp

clamp()とは

clamp()はCSSの関数で、最小値、推奨値、最大値の3つの引数を取ります。

clamp(最小値, 推奨値, 最大値)

最小値要素が取ることができる最小の値を示します。通常、画面が非常に小さい場合や、コンテンツが非常に狭い場合にこの値が適用されます。
推奨値常の状況で要素が持つべき推奨される値です。通常、この値が画面サイズやコンテンツの幅に応じて柔軟に変化します
最大値要素が取ることができる最大の値を示します。通常、画面が非常に大きい場合や、コンテンツが非常に広い場合にこの値が適用されます。

この説明で理解できる人はほぼいないでしょう。

例えば、

.container {
  width: clamp(300px, 50vw,1000px);
}

という記述だと、基本的にwidthが50vwで動きつつ、300pxより小さくならなくならず、1000pxより大きくならなくなるので、

要素がスマホ時に小さすぎたり、PC幅以上の大画面時に大きすぎる状態を防ぐことができます。

具体的な動作を見てみましょう。

これまでのレスポンシブ対応では、テキストサイズは以下のように、メディアクエリを使用してPC、タブレット、SPで段階的に切り替えている人が多かったかもしれません。

clamp関数 css

もしかしたら、vwでレスポンシブ対応している人もいるかもしれませんが、その場合に大画面時に要素が巨大化して違和感が発生しているケースがあります。

clamp関数 css

要は、「PC幅〜のときはPCの固定サイズ、タブレット付近はよしなにフレキシブルに変化して、SPのときはSPデザインの固定サイズ」にしたいのですよね。

それ、clamp()を使えば簡単にできます。例えば以下は滑らかにフォントサイズが変わっているのが分かると思います。

ここではファーストビューのメインコピーだけclamp()を適用しています。

clamp関数 css

ここで使用したコードは以下ですが、

font-size: clamp(3rem, 1rem + 6.67vw, 6rem);

これをメディアクエリを使って書くと、結構めんどくさいです。

@media screen and (max-width: 768px) {
  /* 768px以下の場合 */
  font-size: 3rem;
}

@media screen and (min-width: 768px) and (max-width: 1440px) {
  /* 768px以上1440px以下の場合 */
  font-size: calc(1rem + 6.67vw);
}

@media screen and (min-width: 1440px) {
  /* 1440px以上の場合 */
  font-size: 6rem;
}
推奨値の補足

1rem + 6.67vwという数値は、768px~1440pxの範囲でいい感じにレスポンシブすることを示していますが、この数式は自動で出せるので詳しくは後述します。

もう一つ例を見てみましょう。

こちらはコンテナのwidthと中の見出しのfont-sizeに対してclamp()を使用した例です。

clamp() css

まずコンテナのwidthはこうなっています。

width: clamp(320px, 0.682rem + 82.42vw, 1000px);

これをメディアクエリを使うと、

@media screen and (max-width: 768px) {
  /* 768px以下の場合 */
  width: 320px;
}

@media screen and (min-width: 768px) and (max-width: 1440px) {
  /* 768px以上1440px以下の場合 */
  width: calc(0.682rem + 82.42vw);
}

@media screen and (min-width: 1440px) {
  /* 1440px以上の場合 */
  width: 1000px;
}

font-sizeに関しては以下になっています。

font-size: clamp(1.5rem, 0.364rem + 4.85vw, 4rem);

これをメディアクエリを使うと、

@media screen and (max-width: 768px) {
  /* 768px以下の場合 */
  font-size: 1.5rem;
}

@media screen and (min-width: 768px) and (max-width: 1440px) {
  /* 768px以上1440px以下の場合 */
  font-size: calc(0.364rem + 4.85vw);
}

@media screen and (min-width: 1440px) {
  /* 1440px以上の場合 */
  font-size: 4rem;
}

ただここで疑問が出てきます。

clamp(1.5rem, 0.364rem + 4.85vw, 4rem)

真ん中の推奨値である、0.364rem + 4.85vwはどうやって出せばいいのでしょうか?

clamp()の推奨値ってどうやって計算するの?

デザイナーさん

でも、タブレット付近をよしなにしてくれる真ん中のremとvwが+されてるところとか、どうやって計算すればいいの?

なんかめんどくさそう。。。

これには2つの方法があります。

clamp()を利用する方法
  1. ジェネレーターを使う(初心者におすすめ)
  2. scss関数を組む(Sassに自信ニキにおすすめ)

順番に解説します。

clamp()の利用方法❶ジェネレーターを使う

お試しでとりあえずclamp()を使う程度なら、脳死で「Min-Max-Value Interpolation」を利用して、推奨値を算出すればいいかと思います。

例えばフォントサイズで、

PCデザイン1200pxのときは64px

SPデザイン375pxのときは24px

その間375px~1200pxはよしなに動いて欲しい

こんなときは、この画像のように入力すればOKです。

clamp関数を使ってフォントサイズはレスポンシブで自動調整せよ【計算ツールでラクラク設定】

単位がremになっていますが、どうしてもpxを使いたい人は、remの数値を16倍してpxにしてもいいと思います。

補足:remとpxについて

今回の本題とずれますが、

まさひろくん

remじゃないとダメなのかな?

と思われる方がいるかもなので、補足です。

基本的にアクセシビリティなどの観点からremを使ったほうが良い場合が多く、sassの関数で簡単にpx→remに変換できるので、

まだremに慣れていない人はこのタイミングで導入するといいかなと思います。

// 基準となるフォントサイズを設定
$baseFontSize: 16px;

// pxをremに変換する関数
@function rem($pxValue) {
  @return ($pxValue / $baseFontSize) * 1rem;
}

// 使用例
.box h1 {
  font-size: rem(24px); // 24pxを16px基準のremに変換
}

もしclamp()を使うまでも無い場面では、この関数を使えばいいと思います。

clamp()の利用方法❷sassの関数を使う

ありさちゃん

毎回ジェネレーター使うの煩わしいですね。。。

こう思ったなら、Sassで関数を組めばよいでしょう。

以下がclamp()を生成する関数です。

@function rclamp($min, $max, $minViewport, $maxViewport) {
  $vwScale: ($max - $min) / ($maxViewport - $minViewport);  // vw単位でのスケールを計算
  $baseOffset: $min - $minViewport * $vwScale;  // 基準となる最小値からのオフセットを計算

  $minRem: $min / 16;  // 最小値をremに変換
  $maxRem: $max / 16;  // 最大値をremに変換
  $baseOffsetRem: $baseOffset / 16;  // オフセットをremに変換
  $vwScaleRem: $vwScale * 100;  // vwスケールを調整

  @return clamp(#{$minRem}rem, #{$baseOffsetRem}rem + #{$vwScaleRem}vw, #{$maxRem}rem);
}

// 使用例
.example {
  font-size: rclamp(24, 64, 375, 1200);
}
@function clamp-vw($min, $max, $minViewport, $maxViewport) {
$vwScale: ($max - $min) / ($maxViewport - $minViewport);  // vw単位でのスケールを計算
$baseOffset: $min - $minViewport * $vwScale;  // 基準となる最小値からのオフセットを計算  $minRem: $min / 16;  // 最小値をremに変換
$maxRem: $max / 16;  // 最大値をremに変換
$baseOffsetRem: $baseOffset / 16;  // オフセットをremに変換
$vwScaleRem: $vwScale * 100;  // vwスケールを調整  @return clamp(#{$minRem}rem, #{$baseOffsetRem}rem + #{$vwScaleRem}vw, #{$maxRem}rem);
}

実際に使う際には、

rclamp(最小値, 最大値, 最小viewport,最大viewport)

を入力することで、コンパイル後のCSSでclamp()が生成されます。

関数定義の下に使用例を載せていますが、この使用例だと、以下の画像と同じ値が出力されます。

clamp関数を使ってフォントサイズはレスポンシブで自動調整せよ【計算ツールでラクラク設定】

補足:自作関数の詳細説明

この関数の詳細な動きを知りたい人向けに、一応噛み砕いて説明しておきます。

とはいえかなり難しいので、理解できなければとりあえず飛ばして関数だけ利用しておけばOKです。

関数定義

@function rclamp($min, $max, $minViewport, $maxViewport) {
  • rclamp関数は、4つのパラメータを受け取ります。
    • $min$max は、フォントサイズの最小値と最大値(ピクセル単位で指定)。
    • $minViewport$maxViewport は、このフォントサイズ調整を適用するビューポートの最小幅と最大幅(ピクセル単位)。

計算

  $vwScale: ($max - $min) / ($maxViewport - $minViewport);  // vw単位でのスケールを計算
  $baseOffset: $min - $minViewport * $vwScale;  // 基準となる最小値からのオフセットを計算
  • $vwScale は、ビューポートが $minViewport から $maxViewport に変化する間に、フォントサイズがどれだけ変わるかの比率を計算します。
  • $baseOffset は、最小ビューポート幅でフォントサイズが $min になるように調整するためのオフセットを計算します。

単位変換

  $minRem: $min / 16;  // 最小値をremに変換
  $maxRem: $max / 16;  // 最大値をremに変換
  $baseOffsetRem: $baseOffset / 16;  // オフセットをremに変換
  $vwScaleRem: $vwScale * 100;  // vwスケールを調整
  • ここで、フォントサイズとオフセットの単位をピクセルから rem に変換しています。通常、1remはブラウザの基本フォントサイズ(多くの場合16px)に相当します。これにより、スタイルの設定がより柔軟になります。
  • $vwScaleRem は、vw スケールを100倍にして、vw単位がビューポート幅の百分率を反映するように調整しています。

clamp() 関数のリターン部分

  @return clamp(#{$minRem}rem, #{$baseOffsetRem}rem + #{$vwScaleRem}vw, #{$maxRem}rem);
  • ここでは計算された値を使用してCSSの clamp()を構築し、フォントサイズがビューポートの幅に応じて柔軟に調整されるようにします。
  • clamp() の第一引数は最小値、第三引数は最大値、第二引数はビューポート幅に応じて変化する中間の値です。

使用例(ここが理解できればOK)

ここまで関数を指定したので、その使用例です。

この関数の使い方だけ覚えて貰えれば今回は特に問題ありません。

.example {
  font-size: rclamp(24, 64, 375, 1200);
}

ここで指定された数値は、ピクセル単位での最小値、最大値、ビューポートの最小幅、最大幅です。

この値の場合、CSSにコンパイルしてみると、実際にSassで定義した独自関数の中では以下の処理が行われます。

$minRem = 24 / 16 = 1.5rem
$maxRem = 64 / 16 = 4rem
$vwScale = (64 - 24) / (1200 - 375) = 40 / 825 ≈ 0.0484848
$vwScaleRem = 0.0484848 * 100 = 4.84848vw
$baseOffset = 24 - 375 * 0.0484848 ≈ 6.18181818
$baseOffsetRem = 6.18181818 / 16 ≈ 0.38636364rem

そうしてこの関数内での計算の結果、CSSのclamp()として出力された時に、

clamp(1.5rem, 0.38636364rem + 4.8484848485vw, 4rem)

というように最小、最大値はremで、推奨値では、rem+vwの値が出力されます。

これによって、タブレット付近でいい感じに大きさが変化してくれるわけです。

しょーご

Sassの関数の処理がわからなかった人は、この具体的数値を入れた処理の流れと同時に見ると分かりやすいと思います。

clamp()の実用例

では、今日学んだことの実践です。

例えばPCデザイン時に1440pxfont-size96pxだったとして、

スマホデザインでは、375pxfont-size48pxのときはどう設定しますか?

ジェネレーターとSass独自関数の2つの例をみていくと、

ジェネレーターを使う場合は、以下のような指定になり、

Sassの関数を使う場合は、

font-size: rclamp(48, 96, 375, 1440);

この指定にすればいいですね!

試しにCSSに出力された結果を見ると、

font-size: clamp(3rem, 1.9436619718rem + 4.5070422535vw, 6rem);

となっていて、ジェネレーター出力の数値よりも桁数が多いですが、ほぼ同じ数値になっているのが分かります。

clamp()がsafariで動かない場合

safariのバージョンによってはclamp関数が動かない場合があるので、そのときは

* {
    min-height: 0vw;
}

これを加えるようにしてください。

clamp()のデメリット

タブレットデザインに柔軟に対応できない

タブレット付近はよしなに動いて貰う関数なので、もし

ゆうきくん

タブレットデザインでピクセルパーフェクトにならないんですけど!!

という場合は向きません。

しかし、私はそんな丁寧な現場に出会ったことが無いです。

強いていえば、タブレット時に柔軟に変化する仮定で他の要素とぶつかる可能性はあるので、そこは丁寧に検証する必要はあるかと思います。

まとめ clamp()の可能性は無限大!

基本的にclamp()はフォントサイズに使うことが一番多いですが、

  • PCとSPデザインの数値が異なる
  • PC~SPデザイン間はよしなに変化させたい

このような場合には、width、padding、marginなど幅広く使えるので、是非積極的に使ってみてください!

うまく使えれば、メディアクエリをわざわざ分けて書く機会が減ると思います。

ちなみに、今回題材として動画で挙動をお見せしたのは、私が出しているデザインカンプからのコーディング練習課題の上級編になるので、

腕試しされたい方は、是非挑戦してみてください💪

【上級】デザインカンプからのコーディング実践演習【WordPress実案件レベル】

模擬案件チャレンジ開催のお知らせ

超実践編では納期厳守の模擬案件を経験し、スキル面以外にコミュニケーションも徹底レビューを受けることができます。

【超実践編】納期厳守の模擬コーディング案件で実務への自信を身につける!【学習沼からあなたを卒業させます】

最近は実案件のノウハウも多いですが、「納期が短い案件の中で、丁寧なコミュニケーションを本当に実践できますか?

この課題では、極限まで実案件に近い状況で、発注者である私とコミュニケーションを取りながら、

  1. 見積書提出
  2. 実装→初稿提出
  3. レビュー→修正
  4. 再修正→納品
  5. 請求書

この流れを実践していただき、最後にzoomであなたに全体レビューを行います。

【超実践編】納期厳守の模擬コーディング案件で実務への自信を身につける!【学習沼からあなたを卒業させます】
  • 学習はだいたい終わったけど、納期までに納品できるか不安
  • 中々継続と紹介で案件が回らない

このような中級者を飛躍させる超実践編、受講には条件がありますので、詳細はリンク先よりご確認下さい。

しょーご

あなたの挑戦を待っています!!

\レビューを受けて圧倒的な自信を身につける!/

投げ銭機能を設置しました!

寄付とメッセージには全て目を通させていただきます!

🍺 ビールをプレゼントする

あなたに是非読んでほしい記事です!