開発

【CSS】marginやpadding、font-sizeにも最大値や最小値を設定する方法

CSSの比較関数と呼ばれるmin(), max(), clamp()についてご存知でしょうか?使い方に少しクセはありますが、これらを使いこなせれば要素の幅の制御などはもちろん、「marginやpadding、font-sizeにもレスポンシブな理想のサイズに加えて最小サイズ・最大サイズをつける」ということができます。

この記事にはvwが出てくるため、vwやvhの基本に関する記事もあわせてご覧ください。

min()関数

min()関数は、指定した複数の値の中から最も小さい値を選んで適用する機能を持ちます。これを使うことで、要素が大きくなりすぎないように設定することが可能になります。

具体的な例を挙げます。

.min_test_box {
    width: min(100px, 50vw);
}

というコードがあった場合、この関数は2つの値、100pxと50vw(ビューポートの幅の50%を意味する)のうち、小さい方を選びます。画面が広い時(ビューポートの幅が200px以上の時)、50vwは100pxよりも大きな値になります。この場合、min()関数は小さい方の100pxを選び、その要素に適用します。一方、画面が狭い時(ビューポートの幅が200px未満の時)、50vwの方が小さくなり、その値が選ばれます。

また、min()関数には順番や比較する値の個数の指定はなく、比較して小さい値が選ばれます

.min_test_box {
    width: min(100px, 50vw, 20%);
}

この場合、ビューポートや親要素のサイズに応じて、これら3つの値の中から最も小さい値が選ばれます。

max()関数

max()関数は、複数の値から最も大きい値を選んで適用させる関数です。この関数を使うと、要素が一定のサイズ以上にさせることができます。つまり、要素が小さくなりすぎないように設定することができます。
こちらのコードを考えてみましょう。

.max_test_box {
    width: max(100px, 50vw);
}

この場合、2つの値が比較されます。100pxとビューポート幅の50%です。ビューポートが200px幅の場合、50vwは100pxとなりますが、max()関数は2つの値のうち大きい方、つまり100pxを選択します。ビューポートが例えば400pxの場合は、50vwは200pxとなり、この場合max()関数は200pxを選択します。

max()関数もmin()関数と同様に順番や比較する値の個数の指定はなく、比較して大きい値が選ばれます

clamp()関数

clamp()関数は、ある要素のサイズを動的に調整するための便利なCSS関数です。
この関数を使うと、特定の要素がある最小値より小さくならないようにしつつ、ある最大値を超えないように制限することができます。そして、これらの最小値と最大値の間で、要素のサイズは柔軟に変化します。
関数の基本形は順番の指定があり、clamp(最小値, 理想値, 最大値)と記述します。

  • 最小値は、要素が取り得る最小のサイズを指定します。
  • 理想値は、要素のサイズとして理想的だと思われる値で、この値はビューポートのサイズなどに応じて調整されます。
  • 最大値は、要素が取り得る最大のサイズを指定します。

具体的には以下のコードのように記述します。

.clamp_test_box {
    width: clamp(100px, 50vw, 800px);
}

例えば上記のコードは、要素の最小値が100ピクセル、最大値が800ピクセルになるように指定しています。そして、ビューポート(ブラウザの表示領域)の幅が変わると、要素のサイズは理想値の50vwに調整されるように動的に変化しますが、それでも最小値と最大値の範囲内に収まるように制限されます。

このようにclamp()関数を使用することで、画面サイズが変わってもデザインを保ちつつ、要素が画面からはみ出したり、逆にあまりにも小さくなったりするのを防ぐことができます。レスポンシブデザインにおいて非常に有用なツールです。

実際の使用例

テキストのサイズ調整

.catch {
    font-size: clamp(1.8rem, 7vw, 4.0rem);
}

この例では、テキストのサイズがビューポートの幅に応じて調整され、最小で1.8rem、最大で4.0remに保たれます。
メインビジュアルの上に乗せるキャッチコピーなどに活用できるでしょう。

コンテナの幅制限

.box {
    width: max(300px, 50vw);
}

コンテナの幅が50vwを超えないようにしつつ、最小でも300pxは確保されます。

marginの設定

.margin-example {
    margin: 10px min(10vw, 50px);
}

10vwと50pxのうち、小さい方を左右のマージンとして適用します。つまり、ビューポートが広がってもマージンは最大50pxまでしか増えないため、要素の外側のスペースが過剰に広がることを防ぎます。

比較関数の中でcalcも使用する

min(), max(), clamp()のようなCSSの比較関数内ではcalc()を使用することができますが、calcと記述する必要はありません。これは、min(), max(), clamp()関数自体が計算を行う能力を持っており、異なる単位や値を直接扱うことができるためです。つまり、これらの比較関数はcalc()の機能を内包しており、複数の値や単位の演算を直接行うことが可能です。

例を挙げてみましょう。

.calc-example-1 {
    width: clamp(300px, 50% - 2rem, 100%);
}

.calc-example-2 {
    width: clamp(300px, (50% - 2rem), 100%);
}

.calc-example-3 {
    width: clamp(300px, calc(50% - 2rem), 100%);
}

上記の例は、すべて同じ結果を返します。calcと記述しておいたほうが読みやすくなるため、特に複雑な計算が必要な際には使用するといいでしょう。

注意点

CSSの比較関数min(), max(), clamp()を使用する際には、いくつかの注意点があります。これらの関数は非常に便利で柔軟性が高いものの、適切に使用しなければ予期しないレイアウトの問題を引き起こす可能性があります。

  • パフォーマンスへの影響
    大規模なサイトや複雑なアプリケーションでは、これらの関数を過度に使用すると計算コストが増加し、ページのレンダリングパフォーマンスに影響を及ぼす可能性があります。
    特にclamp()は、ブラウザが最小値、推奨値、最大値を常に計算する必要があるため、適切な場所でのみ使用しましょう。
  • 複雑性の管理
    min(), max(), clamp()を使用すると、CSSが直感的ではなくなり、デバッグが難しくなる可能性があります。特にclamp()は3つの異なる値を扱うため、予期しない挙動を理解するのが難しい場合があります。
    可能な限りシンプルに保ち、必要な場合のみこれらの関数を利用することが重要です。
  • ブラウザの互換性
    これらのCSS関数は比較的新しいため、古いブラウザではサポートされていない場合があります。現在(2024年3月)のところ、主要なブラウザ(Google Chrome, Mozilla Firefox, Safari, Edgeなど)の最新バージョンではサポートされていますが、ターゲット層が古いブラウザを使用している可能性がある場合は、フォールバックスタイルを提供するか、代替の実装方法を検討する必要があります。

ブラウザサポート状況

あまり馴染みのない関数だったかもしれませんが、2024年3月現在、ほとんどの主要なブラウザでサポートされています。

※画像はCan I Useの2024年3月時点のスクリーンショットです。

最新のサポート状況についてはCan I Useをご確認ください。

まとめ

最大値を設定する際はmin()、最小値を設定する際はmax()を使うため、min-width、max-widthの感覚と逆になりますが、min(), max(), clamp()関数を活用することでウェブデザインの柔軟性と応答性を大幅に向上させることができます。これらの関数は、さまざまなデバイスや画面サイズに適応するデザインを実現する上で非常に有効なツールです。

これらの関数を利用することで、テキストサイズの調整やコンテナの幅制限など、さまざまなデザインニーズに応えることが可能になります。特にclamp()関数は、レスポンシブデザインにおいてその真価を発揮し、ユーザーが使用するデバイスに関わらず、最適な使用感を提供するための重要な役割を果たします。

CSSのこれらの比較関数を上手く使いこなすのは少し難しく感じるかもしれませんが、実際にコードを書いてみるとその便利さと強力さを体感できるでしょう。
実例を通じて学び、自分の作業に当てはめてみることが上達の近道です。ぜひ、この記事を参考にして、よりレスポンシブなウェブデザインを目指してください。

アバター画像

r.s

グローワークスのコーダー兼プログラマー。最適なコードでサイトを動かすことに情熱を注いでいます。技術的課題を解決するのが得意です。