CSSのサイズ関数:calc()、min()、max()、clamp()とビューポート単位
ホーム
CSSサイズ関数ラボ
CSSのcalc()、min()、max()、clamp()、vhとdvh、fit-content | We.Inc
ビューポート幅のスライダーを動かすと、calc()、min()、max()、clamp()が実際のピクセル値に変わる様子を確認できます。さらにvhとsvh、lvh、dvhの違い、fit-contentとmin-contentの実演、gap、可変フォントサイズのレシピも紹介します。
CSSの数学関数を使うと、1つの値を画面サイズに合わせて変化させられます。calc()を使うと、calc(100% - 2rem)のように異なる単位を1つの式の中で組み合わせられます。min()は候補の中で最も小さい値を選ぶので、width: min(100%, 640px)と書けば要素がはみ出すことはありません。max()は反対に最も大きい値を選びます。clamp(最小値, 推奨値, 最大値)は、画面に合わせて変化する値を、決めた下限と上限の間に収めます。また動的な単位であるdvhは、従来の単位とは違って、モバイルブラウザーで伸び縮みするツールバーの動きに追従します。
目的別に、どの関数を使えばよいか
全幅から固定の余白を引く width: calc(100% - 2rem)
最大でも640pxまでの段組み width: min(100%, 640px)
1remより小さくならない余白 padding: max(1rem, 4vw)
2remから3.5remの間で拡大縮小する見出し font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem)
モバイルで見えている画面いっぱいに広がるヒーロー min-height: 100dvh
数式の動きを試すために、ブラウザーのウィンドウを何度もリサイズする必要はもうありません。疑似的なビューポート幅をスライダーで動かすだけで、それぞれの関数がその場でピクセル値に変わり、clamp()が上限や下限に達する位置にも印が付きます。このページではさらに、スマートフォンの画面上でビューポート単位の4種類がそれぞれどの範囲を測っているかを図で示し、内在的なサイズを表すキーワードが実際のボックスでどう働くかも確認できます。
まず、ビューポート幅のスライダーを、スマートフォンほどの幅から大きなモニターの幅まで動かしてみます。 範囲指定の式の最小値、推奨値、最大値を調整し、計算結果のピクセル値がどのように変わるかを確認します。 同じ幅のとき、ほかの関数の各行がそれぞれどの値になるかを見比べます。 気に入った式をコピーしたら、ページの下のほうにある、コンテンツに合わせてサイズが決まるボックスや要素間の間隔の例も試してみてください。
計算式の中で使う+と-の前後には、必ず空白を入れてください。calc(100%-2rem)は無効で、calc(100% - 2rem)なら正しく動きます。 文字サイズを可変にする式では、真ん中の値にルート基準の単位の項を必ず残しておきましょう。そうしておけば、読み手がブラウザーで拡大表示したり、既定の文字サイズを変更したりしても、文字の大きさがきちんと反応します。 最小値を選ぶ関数と最大値を選ぶ関数は、使い始めたばかりのころは、役割が名前と逆のように感じられます。min()は常に小さいほうの値を取るため、結果として最大サイズを決める役割になるのです。 画面全体を使うセクションで動的な単位を使うのは控えめにしましょう。ツールバーが動くたびに値が変わるため、スクロールしている最中にコンテンツの位置がずれてしまうことがあります。表示を安定させたい場合は、小さいビューポートの単位を選びます。
よくある質問
vh、svh、lvh、dvhの違いは何ですか?
スマートフォンでは、スクロールに合わせてブラウザーのツールバーが表示されたり隠れたりします。svhはツールバーが表示された状態の小さいビューポートの1%で、lvhはツールバーが隠れた状態の大きいビューポートの1%です。dvhはその時点の状態に合わせて変わり、スクロールするたびに更新されます。従来の単位は通常、大きいビューポートと同じ値になります。そのため100vhのセクションはモバイルで下が切れてしまうのです。
clamp()、min()、max()はどのブラウザーでも使えますか?
はい。この3つの関数は、2020年以降、主要なすべてのブラウザーで問題なく動作しています。一方、小さい・大きい・動的なビューポート単位は少し遅れて2022年中に登場しましたが、現在では主要なブラウザーのすべてに搭載されています。古い端末もサポートする必要がある場合は、その前の行に従来の単位を使った代替の指定を書いておきましょう。
clamp()で可変のフォントサイズを書くには?
まず、狭い画面のときと広い画面のときの文字サイズをそれぞれ決めます。次に、clamp(小, 推奨値, 大)という形で書きます。推奨値には1rem + 2vwのように、ルート基準の単位と画面幅基準の単位を組み合わせた値を使います。こうすると、ウィンドウの幅に合わせて文字が大きくなりながらも、決めた下限と上限の間に必ず収まります。下のラボを使えば、上限や下限が効き始める正確な画面幅を確認できます。
fit-contentは何をしますか?
width: fit-contentを指定すると、ボックスの幅がコンテンツの大きさに合わせられます。中身にぴったり縮むインラインブロックのような動きですが、使える幅より広くなることはありません。これはmin(max-content, max(min-content, available space))と同じ意味です。グリッドのトラックで使う同名の関数は、自分で決めた上限を使って同じことを行います。
要素間の間隔の指定はflexboxでも使えますか?
はい。gap、row-gap、column-gapは、グリッドだけでなく現在のすべてのブラウザーのフレックスコンテナでも使えます。間隔は要素と要素の間にだけ追加され、外側の端には付きません。子要素の一つひとつにマージンを付けて調整するよりも、ずっとシンプルに書けます。
calc()が値を決める仕組み
計算式の関数は、ブラウザーがレイアウトを計算する時点まで値の確定を待ちます。そのため、親要素に依存するパーセント値と、ルート基準の単位やピクセルの値を組み合わせられます。この関数はほかの数学関数の中に入れ子にでき、calc(var(--gutter) * 2)のように中でカスタムプロパティを使うこともできます。 掛け算と割り算では、少なくともどちらか一方が単位を持たない数値でなければなりません。calc(2 * 1rem)は問題ありませんが、calc(1rem * 1rem)は使えません。また、0で割ると、その宣言全体が無効として扱われます。
内在的なサイズ:min-content、max-content、fit-content
min-contentは、はみ出さずにボックスを縮められる最小の幅のことで、通常は最も長い単語や最も幅の広い画像の幅になります。max-contentは、テキストが一切折り返さなかった場合の幅です。この2つは、グリッドのトラックを決めるときや、テキストの長さにぴったり沿わせたいラベルを作るときに役立ちます。 3つ目のキーワードはその中間にあたります。コンテンツが求める幅まで広がりますが、コンテナがそれより狭ければ折り返します。そのため、左右の自動マージンと組み合わせれば、中身に合わせて縮んだボックスをきれいに中央に配置できます。
文字だけでなく余白も可変に
範囲指定の同じ手法は、パディング、マージン、要素間の間隔にも使えます。padding-block: clamp(2rem, 6vw, 6rem)を指定したセクションは、大きな画面ではゆったりとした余白で見え、スマートフォンでは限られた画面の余白を無駄にしません。 可変の値は、たとえば--space-mや--step-2のようなカスタムプロパティとして一度だけ定義し、それをあらゆる場所で使いましょう。こうしておけば、後でスケール全体を変えたくなったときも、コンポーネントの中を探し回る必要はなく、1行を書き換えるだけで済みます。
vhとsvh、lvh、dvhの違い
ビューポートに対する割合で表す単位
vh / vw ビューポートの1%(モバイルでは通常、大きいほう) いいえ デスクトップ向けのレイアウトや、古いブラウザーのための代替の指定
svh / svw ツールバーが表示されているときの小さいビューポートの1% いいえ ツールバーで絶対に隠れてはいけない全画面セクション
lvh / lvw ツールバーが隠れているときの大きいビューポートの1% いいえ 画面全体を隙間なく覆うべき背景
dvh / dvw その時点で実際に見えているビューポートの1% はい ツールバーの動きに追従させたいレイアウト
vmin / vmax 短いほう、または長いほうの辺の1% いいえ 画面が縦向きでも横向きでも収まる正方形の要素
cqi / cqw サイズコンテナのインライン方向の大きさの1% コンテナに合わせて変わる コンテナクエリの中で使うコンポーネント
モバイル端末でも安全に画面の高さいっぱいに広がるヒーロー
1行目は、新しいビューポート単位にまだ対応していないブラウザーのための代替の指定です。新しい単位に対応しているブラウザーでは、2行目がその値を上書きします。
calc()、min()、max()、clamp()の使用例
メディアクエリを使わずに作る、読みやすい段組み
最小値を選ぶ関数で幅の上限を決め、パディングには最大値を選ぶ関数を使って12pxより小さくならないようにしています。どちらのルールも、メディアクエリに頼らず、それぞれ単独でフレームの幅に合わせて変化します。
固定幅のサイドバーと可変幅のメインエリアを計算式で並べる
メインエリアは、全体の幅から120pxのサイドバーと12pxの間隔を差し引いた、残りの幅をすべて使って表示されます。
min-content、max-content、fit-content
コンテンツから決まる内在的なサイズを表すキーワード
改行できない最も長い単語、または最も幅の広い画像の幅
枠からはみ出したとしても、すべてのコンテンツを1行に並べたときの幅
1行に並べた幅と同じだが、使える幅より広くはならない
グリッドでのfit-content(300px) 上限が300pxの、中身に合わせるサイズのように動く grid-cols-[fit-content(300px)_1fr]
フレックスとグリッドでのgap
折り返すフレックスの行とグリッドで同じ間隔を使う
行方向と列方向の間隔は、それぞれ別々の値に設定できます。どちらの場合も、外側の端には余白が追加されません。
可変の文字サイズと余白のスケール
カスタムプロパティを使って作る、小さな可変スケール
スケールの各段階は、幅がおよそ360pxのスマートフォンから1280pxのデスクトップまでの間で、少しずつ大きくなります。上のラボを使って、数値を自由に調整してみてください。
ビューポートラボ
疑似ビューポート幅(px)
{px}pxでの可変見出し
疑似的な幅での計算結果
関数
宣言
{vp}pxのとき
clampの最小値(rem)
clampの最大値(rem)
推奨値:remの部分
推奨値:vwの部分
最大値が最小値より小さいため、どの幅でも最小値が使われます。
幅がおよそ{from}pxになるまでは{min}remのまま、およそ{to}pxまで大きくなり、その後は{max}remで止まります。
画面幅基準の部分がないため、ウィンドウの幅が変わっても値は変わりません。
コピー
スマートフォンで各単位の100が覆う範囲
3台のスマートフォン:100svhは表示されたツールバーの間の領域を埋め、100lvhはツールバーが隠れたときのように画面全体を埋め、100dvhはツールバーの変化に追従します
ツールバー表示
ツールバー非表示
ツールバーに追従
灰色の帯はブラウザーのツールバーを表しています。青い部分は、100単位が埋める範囲です。
コンテンツに合わせたサイズの実演
幅のキーワード
使える幅(px)
今週末は、すべてのご注文が送料無料になります
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る