リキッドレイアウトで悩まない!文字も余白も自動で整うCSS雛形
リキッドレイアウトの実装で、画面幅に合わせて「フォントサイズは何pxにすべきか……」と毎回電卓を叩いていませんか?
デバイスごとに細かく計算して数値を打ち込む作業は、時間がかかるだけでなく、微細なズレや計算ミスによるデザインの破綻を招きがちです。
本記事では、一度定義すれば、あとは一切の計算が不要になる「可変レイアウトの雛形」をご紹介します。
応用も簡単なので、参考にしていただければ幸いです。
リキッドレイアウトで使える雛形
この例では、780pxと1400pxのデザインカンプを再現する想定で作成しています。
See the Pen リキッドレイアウト font-size by hisa (@hisaaashi) on CodePen.
まずは、サイト全体の「伸縮の基準」となるカスタムプロパティ(CSS変数)を定義します。
:root {
/* スケール計算:max(最小値の倍率, 画面幅 / デザイン幅) */
--scale: max(0, (100vw / 780px));
@media (min-width: 780px) {
& {
--scale: max(0.8, (100vw / 1400px));
}
}
}実際に文字サイズなどを指定する際は、デザインカンプに記載されているpx数値をそのまま入れるだけです。
.fluid-text {
font-size: calc(32px * var(--scale));
@media (min-width: 780px) {
& {
font-size: calc(16px * var(--scale));
}
}
}ブラウザ内では、指定した数値に対して以下のような計算が自動で実行されます。
- スマホ時:
max(0, (32px * (100vw / 780px))) - PC時:
max(12.8px, (24px * (100vw / 1400px)))
max()関数は「カッコ内の値のうち、大きい方を使用する」という性質を持っているため、画面幅に合わせた「リキッドな可変」をさせつつ、同時に「最小値の設定」まで完結させることができます。
サイズ計算の基礎
リキッドレイアウトとは、画面幅(100vw)を基準に、デザイン上の比率を維持したまま要素を伸縮させる手法です。
その心臓部となるのが、「デザイン幅の1pxが、今の画面では何vwに相当するか」という計算です。
計算の仕組み
- 画面幅 = 100vw
- デザイン幅 = 1400px
この場合、100vw / 1400px ≒ 0.0714… という比率になります。
数値の使い方
この「0.0714…(比率)」をカンプ上のpx数に掛けます。
- 40px(大きな見出し):40 * 0.0714… ≒ 2.86vw
- 16px(標準サイズ):16 * 0.0714… ≒ 1.14vw
この数値を使えば、狙い通りのサイズで可変させることができます。
.text {
font-size: 1.14vw;
}ただし、計算後の値を直接書くと、何から導き出した数値なのかが分からなくなってしまうため、保守性は良くありません。
.text {
font-size: calc(16px * (100vw / 1400px));
}これなら「1400px幅のデザインで16pxだった」という根拠が見て取れます。
しかし、すべての要素にこの計算式を書いて回るのは記述が冗長ですし、もし基準となるデザイン幅が変更になった場合、すべての箇所を書き直すという手間が発生します。
これらの問題を一挙に解決するのが、共通の比率を定義した変数(カスタムプロパティ)の活用です。
カスタムプロパティ化
これが、リキッドレイアウト計算における「基本の雛形」となります。
:root {
/* 基準となる比率を一つだけ定義 */
--scale: (100vw / 1400px);
}
.title {
/* カンプの数値を掛けるだけ */
font-size: calc(40px * var(--scale));
}- 直感的: コードを見ただけで「40pxをスケーリングしている」とすぐ分かる。
- 正確: 面倒な小数点の計算はすべてブラウザに任せられる。
- 高保守性: デザイン幅が変わっても、1箇所変えるだけでサイト全体が即座に同期する。
このままでも使えますが、最小値を設定することで「文字の小さすぎ」を防止することができます。
最小値を設定
単純に流動的なフォントサイズにしてしまうと、デザインによってはブレイクポイント付近(800px付近など)で文字が小さくなり過ぎてしまう場合があります。
それを防ぐために、「最小値」を担保できる max()関数を利用します。
.text {
/* 13px以下にならないように */
font-size: max(13px, (16px * var(--scale)));
}ですが、このような書き方だと「32pxの見出しなら20pxまで」「40pxなら28pxまで」といった具合に、要素ごとに個別の最小値を計算して記述しなければなりません。
「何倍まで小さくするか」を決める
そこで、最小値をpxで指定するのではなく、「元のサイズの何倍まで下げて良いか」という倍率で定義します。
こうすることで、あらゆるサイズの文字に対して相対的に最小値を揃えることができます。
.text {
/* 0.8倍以下にならないように設定 */
font-size: max((16px * 0.8), (16px * var(--scale)));
}- 16pxの場合: 最小12.8pxまで可変
- 40pxの場合: 最小32pxまで可変
この計算を効率よく使い回すために、共通部分を因数分解して整理します。
16px * max(0.8, var(--scale))この「16px」以外の部分、つまりmax(0.8, var(--scale))が、汎用的に使い回せるスケーリングの本体になります。
最小値を含めてカスタムプロパティ化
これまで解説してきた要素をすべて統合したのが、冒頭で紹介したこのカスタムプロパティです。
:root {
/* PC用:1400px幅のデザイン基準。0.8倍(80%)を最小値として設定 */
--scale: max(0.8, (100vw / 1400px));
}
.text {
/* 16pxと書くだけで「可変」と「最小値12.8px」が適用される */
font-size: calc(16px * var(--scale));
}
.title {
/* 40pxと書くだけで「可変」と「最小値32px」が適用される */
font-size: calc(40px * var(--scale));
}最低値設定の考え方
最小値の倍率を「0」にすると、常に計算値(可変側)の方が大きくなるため、制限なくどこまでも縮小させることができます。
/* 常に可変させる(下限なし) */
--scale: max(0, (100vw / 1400px));逆に、ここを「1」にすると、画面をどれだけ狭くしてもデザイン本来のサイズ(1倍)より小さくなることはありません。
/* 縮小させない(デザインサイズを維持) */
--scale: max(1, (100vw / 1400px));最小値をいくつにするかは要件次第ですが、一つの目安として「PC環境での視認性」を基準にするのがおすすめです。
スマホであれば最悪の場合ピンチイン・アウトで簡単に拡大できますが、PCではブラウザ自体のズーム機能を使わない限り、小さすぎる文字を読むのは困難だからです。
デザインと実用性のバランスを考えたら、本文13pxくらいが現実的な落としどころではないでしょうか。
「特定の画面幅以下」でサイズを固定したい場合は、「最小値としたい画面幅 ÷ デザイン幅」で算出した比率を指定すればOKです。
/* 画面幅960px以下でサイズ固定 */
--scale: max((960 / 1400), (100vw / 1400px));応用:最大値も同時に設定
応用で、clapm関数を使用すれば、最小値だけでなく「最大値」も同時に設定可能になります。
:root {
/* 最小値の倍率, 可変比率, 最大値の倍率; */
--scale: clamp(0.8, (100vw / 1400px), 1);
}このように設定すると、画面幅が1400pxを超えても倍率が「1」で固定されるため、指定の文字サイズより大きくなるのを防げます。
余白でも使える
カスタムプロパティに設定したのはあくまで「比率」なので、フォントサイズだけでなくpaddingやmax-widthといった余白・サイズの指定にもそのまま活用できます。
/* カードのコンポーネント例 */
.card {
max-width: calc(540px * var(--scale));
padding: calc(24px * var(--scale));
font-size: calc(28px * var(--scale));
}使い方は同じく、デザインカンプ通りの数値を入力するだけで、余白も幅も、文字サイズと同期して可変します。
remも使えるが挙動が不安定
remを使えば文字拡大に対応できそうですが、環境によって挙動が異なるため併用は避けるのが無難です。
.text {
font-size: calc(1rem * var(--scale));
}iPhoneで「テキストサイズ拡大」を検証した結果、以下のようになりました。
- Chrome:想定通り大きくなる
- Safari:逆に小さくなる(逆転現象)
Safariでは拡大した際に、計算の基準にしている「画面の幅(vw)」の解釈がズレてしまうことが原因と考えられます。(※バグの可能性もあり)
拡大にしっかり対応させるなら、従来どおり「rem のみ」を指定するなど、使い分けが必要です。
/* デザイン維持:カンプ通りに可変させる */
.text {
font-size: calc(16px * var(--scale));
}
/* 拡大対応(本文など) */
.content p {
font-size: 1rem;
}まとめ
コーディング効率と保守性を考え、このようなカスタムプロパティ化を考えてみました。
実務で使用する際は、バッティングしないカスタムプロパティ名に変更し、役割や使い方などコメントしておくことをおすすめします。

カスタマイズに困ったらお気軽にご相談を!
- 「ちょっとしたCSSの調整だけお願いしたい」
- 「不具合を直してほしい」
料金は3,000円〜、お支払いは銀行振込・Amazonギフトカードなど柔軟に対応してます🤔
お気軽にコメントどうぞ