🗜️

CSSのclamp()を便利に使うscssの関数

2023/10/06に公開

こんにちは。
どうも柴田です。

みなさん clamp() は使っていたりしますか?

僕は結構使ってたりします。

これは、IE11とかはダメなので、IE11にも対応するような案件では使えませんが、
まぁ、今やほとんどないと思うのでそろそろ使っても問題ないと思います。

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

これは、min()max() を組み合わせて代用できるのですが、最小値と推奨値、最大値を指定してサイズを調整できるCSSの関数です。

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

例えば、基本的には 5vw のようにウインドウの幅に対して可変するようなサイズにしたいけど、20px より小さくはなってほしくないし、100px より大きくはなってほしくない。

みたいな時に活用できます。

font-size で上記のようなことをしたければ、以下のようなCSSになります。

p {
  font-size: clamp(1.25rem, 5vw, 6.25rem);
}

clamp() の中は、calc() のように計算もできるので、計算式を入れてもいいかもです。

p {
  font-size: clamp(20 / 16 * 1rem, 5vw, 100 / 16 * 1rem);
}

rem を使っているのでブラウザの文字サイズ変更機能を利用した際に、最小値と最大値に関しては機能します。

ただ、推奨値の部分はやはり vw なので変わりません。

なので、そうですね・・・。例えばウインドウを広げて大体、文字サイズが30pxくらいになっている時に、文字サイズの変更機能で文字サイズを変えても何も変化しないって感じです。

そもそも、今回のケースであれば 30pxくらいあれば小さすぎて読めないってことはないので、機能しなくても困らないかもですが、最小値が10pxとか、12pxくらいになっている時はやはり変化できないと辛いかもしれません。

その場合は、推奨値もremem を混ぜるといいです。

vw だけじゃなく、rem + vw のように 文字に対する相対値と足し算してあげたらその rem の部分に文字サイズの変更機能が利用できます。

どうやって計算するのかってのが難しいですが、便利なサイトなんかもあります。

例えばこれです。

https://min-max-calculator.9elements.com/

ただ、毎回ジェネレーターでコードを生成するのもちょっと面倒なのと、僕はまだScssを使ってたりするので、
Sass/Scssでオリジナルの関数を作ってこれをやってます。

@function myClamp($min, $max, $min-view-port: 320, $max-view-port: 1200) {
  $valiable-part: calc(($max - $min) / ($max-view-port - $min-view-port));
  $constant: calc(($max - $max-view-port * $valiable-part) / 16);
  $min-rem: calc($min / 16 * 1rem);
  $max-rem: calc($max / 16 * 1rem);
  $variable-rem: calc($constant * 1rem);
  $variable-vw: calc(100 * $valiable-part * 1vw);

  @return clamp($min-rem, $variable-rem + $variable-vw, $max-rem);
}

のような感じですかね。
これで、基本は以下のように最小値と最大値を px でセットしたらいけます。(remに変換されます)

p {
  font-size: myClamp(20, 100);
}

ビューポートの最小値と最大値も変更したい場合は、第三引数や第四引数をしていします。

p {
  font-size: myClamp(20, 100, 300, 1920);
}

と、こんな感じです。

Scssを使わずにカスタムプロパティだけでもこういう関数的なものを作ったりしてみたんですが、めっちゃ使いにくかったのでとりあえず現状はこんな感じで使ってます。

ということで、こんな感じの記事は普段、僕がやっているShibajukuというオンラインサロンの中に書いてるのですが、ちょっとZennを使ってみたくて、ここに書いてみました。

https://community.camp-fire.jp/projects/view/96755

ちなみに、サロン内にもこの記事も基本はサロン内に書いた記事と同じです。サロン内の方は、Demoとかも用意してます。

では。

Discussion