Webデザイン

min関数、max関数、clamp関数を使って要素のサイズを柔軟に指定する

柔軟なサイズ指定を実現するCSSの関数min(),max(),clamp()

どうもこんにちは。
Web/App/UIデザイナーのサトウです。

今回は、min関数、max関数、clamp関数を使って色々なサイズを柔軟に指定する方法をご紹介します。

2つ以上の数値を比較して柔軟に振る舞うmin関数とmax関数

min関数とmax関数は、ある要素のあるサイズに対して2つ以上の数値を指定しておくと、ブラウザの状態から計算してふさわしい数値を採用してくれるというものです。

  • 基本的には1000pxだけど、100%よりは大きくならないでね
  • 基本的には50vhだけど、400pxよりは小さくならないでね

といったような指定ができます。

  • width と max-width, height と max-height
  • width と min-width, height と min-height

の組み合わせをまとめて指定できると考えるとわかりやすいです。

さらに、min関数とmax関数はfont-sizeに対しても使用できます
これが地味に便利です。

min関数とmax関数は、仕様上は「2つ以上」の数値を比較対象として指定できます。
が、3つ以上の数値を指定する局面はあまりないと思います。
基本的には2つの数値を指定する使い方になるのではないでしょうか。

min関数とmax関数の記述方法

min関数

min関数は、最大値を指定します。
「2つ以上の数値のいちばん小さいものを算出して、それより大きくならないでね」という指定方法です。

element {
  property: min(value1, value2);
}

max関数

max関数は、最小値を指定します。
「2つ以上の数値のいちばん大きいものを算出して、それより小さくならないでね」という指定方法です。

element {
  property: max(value1, value2);
}

min関数、max関数とも、value1、value2の一方には絶対値(px, pt, rem)を指定し、もう一方には相対値(%, vw, vh)を指定します。

min関数の使用例

ブロック要素の幅を制御

700pxと100%を比較して、その時点で小さいほうを採用。
<style>
.min-box {
  background: #afafff;
  padding: 1em;
  margin: 0 auto;
  width: min(700px, 100%);
}
</style>

<div class="min-box">
  700pxと100%を比較して、その時点で小さいほうを採用。
</div>

親要素、またはブラウザの横幅の100% < 700px →「100%」の指定を採用
親要素、またはブラウザの横幅の100% ≧ 700px →「700px」の指定を採用

例えば、コンテンツの幅を、モバイルでは100%、PCでは1000pxというふうに指定したいときなどに便利です。

フォントサイズを制御

16pxと2vwを比較して、その時点で小さいほうを採用。
<style>
.min-text {
  font-size: min(16px, 2vw);
}
</style>

<div class="min-text">16pxと2vwを比較して、その時点で小さいほうを採用。</div>

2vw < 16px →「2vw」の指定を採用
2vw ≧ 16px →「16px」の指定を採用

2vwが16pxより小さくなるのは100vwが800px未満のときです。
つまり、画面幅が800px以上のときはfont-size:16px;、画面幅が800px未満の時はfont-size:2vw;の指定になります。
幅の狭い画面でも、1行の文字数、改行位置をしっかりと制御したい場合などに便利です。

max関数の使用例

ブロック要素の幅を制御

700pxと100%を比較して、その時点で大きいほうを採用。
<style>
.max-box {
  background: #afffaf;
  padding: 1em;
  margin: 0 auto;
  width: max(700px, 100%);
}
</style>

<div class="max-box">
  700pxと100%を比較して、その時点で大きいほうを採用。
</div>

親要素、またはブラウザの横幅の100% < 700px →「700px」の指定を採用
親要素、またはブラウザの横幅の100% ≧ 700px →「100%」の指定を採用

ブラウザの幅いっぱいにコンテンツを表示させたい場合で、幅の狭いブラウザでは横スクロールを出してでも最低限のコンテンツ幅を確保したいというような場合に便利です。

フォントサイズを制御

16pxと2vwを比較して、その時点で大きいほうを採用。
<style>
.max-text {
  font-size: max(16px, 2vw);
}
</style>

<div class="max-text">16pxと2vwを比較して、その時点で大きいほうを採用。</div>

2vw < 16px →「16px」の指定を採用
2vw ≧ 16px →「2vw」の指定を採用

2vwが16pxより大きくなるのは100vwが800px以上のときです。
つまり、画面幅が800px未満のときはfont-size:16px;、画面幅が800px以上の時はfont-size:2vw;の指定になります。
幅の広い画面向けに幅いっぱいのコンテンツを制作する場合で、1行の文字数、改行位置をしっかりと制御したい場合などに便利です。

最小値から最大値の間で柔軟に振る舞うclamp関数

clamp関数は、ある要素のあるサイズに対して「最小値」「推奨値」「最大値」の3つの数値を指定しておくと、ブラウザの状態から計算してふさわしい数値を採用してくれるというものです。

min関数/max関数と同様、clamp関数も、font-sizeに対しても使用できます。

  • 基本は幅100%だけど、1000pxより大きくならず、600pxより小さくならないでね
  • 基本はフォントサイズ2vwだけど、16pxより大きくならず、12pxより小さくならないでね

といったような指定ができます。

clamp関数の記述方法

clamp関数は、「最小値」「推奨値」「最大値」の3つの数値を指定します。
「『最小値と最大値の間で』という条件付きで推奨値を採用してね」という指定方法です。

element {
  property: clamp(min-value, preferred-value, max-value);
}

clamp関数の使用例

ブロック要素の幅を制御①

width: clamp(50vw, 1000px, 100vw);
吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれ

このピンク色のdivは、普通にPCで見ると幅1000pxになっていると思いますが、ブラウザを横に広げていき、ブラウザの幅が2000pxを超えると、divは幅が最小設定値の50vwを下回らないように広がり始めます。
逆に、ブラウザの横幅を縮めていくと、ブラウザの幅が1000pxを下回ったとき、divは幅が最大設定値の100vwを上回らないように縮み始めます。

<style>
.clamp-box-1 {
  background: #ffafaf;
  padding: 1em;
  margin: 0 auto;
  width: clamp(50vw, 1000px, 100vw);
}
</style>

<div class="clamp-box-1">
  width: clamp(50vw, 1000px, 100vw);
</div>

1000px > 100vw → 100vwを採用
100vw ≦ 1000px ≧ 50vw → 1000pxを採用
1000px < 50vw → 50vwを採用

ブラウザ幅1000px未満でwidth:100vw;を採用、ブラウザ幅1000px〜2000pxの間はwidth:1000px;を維持し、ブラウザ幅が2000pxを超える(50vwが1000pxを超える)とwidth:50vw;を採用します。

モバイルでは全幅、PCでは幅1000pxを維持しつつ、幅の広い画面に対しては50%の幅で左右の余白とバランスをとる、といったケースで便利です。

ブロック要素の幅を制御②

width: clamp(600px, 100vw, 1000px);
吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれ

この黄色のdivは、普通にPCで見ると幅1000pxになっていると思います。最大設定値が1000pxなので、ブラウザを横に広げていってもdivの幅は1000pxのままです。
逆に、ブラウザの横幅を縮めていくと、ブラウザの幅が1000pxを下回ったとき、divは推奨値の100vwに幅を維持し、ブラウザの幅が600pxを下回ったとき、divの幅は最小設定値の600pxに固定されます。

<style>
.clamp-box-2 {
  background: #ffffaf;
  padding: 1em;
  margin: 0 auto;
  width: clamp(600px, 100vw, 1000px);
}
</style>

<div class="clamp-box-2">
  width: clamp(600px, 100vw, 1000px);
</div>

600px > 100vw → 600pxを採用
1000px ≧ 100vw ≧ 600px → 100vwを採用
100vw > 1000px → 1000pxを採用

ブラウザ幅600px未満でwidth:600px;を維持、ブラウザ幅600px〜1000pxの間はwidth:100vw;を採用し、ブラウザ幅が1000pxを超えるとwidth:1000px;を維持します。

PC等幅の広い画面ではコンテンツ幅1000px固定、画面の幅が狭まるとコンテンツ幅も全幅で展開するものの、あまりにも幅の狭い画面では横スクロールさせてでもレイアウトを維持したい、といったケースで便利です。

フォントサイズを制御

2vwが12pxを下回らず、かつ16pxを上回らない限り2vwを採用
<style>
.clamp-text {
  font-size: clamp(12px, 2vw, 16px);
}
</style>

<div class="clamp-text">2vwが12pxを下回らず、かつ16pxを上回らない限り2vwを採用</div>

2vwという、画面幅に対して相対的なサイズでフォントサイズを指定するケースです。
が、可読性やデザインとの兼ね合いを考慮して最小12px、最大16pxという制限を設けています。

12px > 2vw → 12pxを採用
12px ≦ 2vw ≦ 16px → 2vwを採用
16px < 2vw → 16pxを採用

2vwが12pxを下回るのは100vwが600px未満のとき、2vwが16pxを上回るのは800px以上のときです。
つまり、画面幅が600px未満ではfont-size:12px;を維持し、画面幅600px〜800pxでfont-size:2vw;を採用、画面幅が800pxを超えるとfont-size:16px;を維持するということになります。

min関数、max関数、clamp関数の数値指定にはcalc関数が使える

min関数、max関数、clamp関数で数値を指定する際にはcalc関数を使うことができます。
例えばこんなふうに。

element {
  font-size: min(calc(value1 * value2), calc(value3 * value4));
}

モバイル/PC共通デザインのコーディング時に便利

これを活用すると、デバイスの画面幅に関わらず、コンテンツエリアの幅に対してフォントサイズを指定するような使い方ができます。
全デバイス共通で使われる画像の中に、レイアウトを崩さずに画像のような扱いでテキストを配置したいケースなどで便利です。

メリークリスマス!

Merry
Christmas!

このブログは幅広の画面で右側にサイドバーがあるので、そういった場合にはまた別途対応が必要になりますが、1カラムのLPでモバイル/PC共通デザインというようなケースではこれで対応できます。
下記動画のようなイメージです。

コンテンツの幅は750px以下の100vwを想定。
フォントサイズはコンテンツ幅が750pxのときはコンテンツ幅×0.048px、コンテンツ幅が100vwのときは4.8vwとしています。

<style>
.flexible-text-box {
  position: relative;
  width: min(100vw, 750px);
  margin: 0 auto;"
}
.flexible-text{
  position: absolute;
  top: 50%;
  left: 7%;
  transform: translate(0, -50%);
  font-size: min(4.8vw, calc(750px * 0.048));
  font-weight: 600;
  color: #e90230;
}
</style>

<div class="flexible-text-box">
  <img src="https://kaisha-yameta.com/wp/wp-content/uploads/2022/12/MerryChristmas.jpg" alt="メリークリスマス!" width="1500" height="940" class="aligncenter size-full wp-image-20356 post-content-image" />
  <div class="flexible-text">
    Merry
    Christmas!
  </div>
</div>

さて、今回は、min関数、max関数、clamp関数を使って色々なサイズを柔軟に指定する方法をご紹介しました。
いかがだったでしょうか?
読んでくださったあなたの参考に少しでもなれば嬉しいです。
それではまた次回。