リキッドレイアウトで悩まない!文字も余白も自動で整うCSS雛形

リキッドレイアウトの実装で、画面幅に合わせて「フォントサイズは何pxにすべきか……」と毎回電卓を叩いていませんか?

デバイスごとに細かく計算して数値を打ち込む作業は、時間がかかるだけでなく、微細なズレや計算ミスによるデザインの破綻を招きがちです。

本記事では、一度定義すれば、あとは一切の計算が不要になる「可変レイアウトの雛形」をご紹介します。

応用も簡単なので、参考にしていただければ幸いです。

目次

リキッドレイアウトで使える雛形

この例では、780pxと1400pxのデザインカンプを再現する想定で作成しています。

See the Pen リキッドレイアウト font-size by hisa (@hisaaashi) on CodePen.

まずは、サイト全体の「伸縮の基準」となるカスタムプロパティ(CSS変数)を定義します。

:root {
  /* スケール計算:max(最小値の倍率, 画面幅 / デザイン幅) */
  --scale: max(0px, (100vw / 780));

  @media (min-width: 780px) {
    & {
      --scale: max(0.8px, (100vw / 1400));
    }
  }
}

実際に文字サイズなどを指定する際は、デザインカンプに記載されているpx数値をそのまま入れるだけです。

.fluid-text {
  font-size: calc(32 * var(--scale));
  

  @media (min-width: 780px) {
    & {
      font-size: calc(16 * var(--scale));
    }
  }
}

ブラウザ内では、指定した数値に対して以下のような計算が自動で実行されます。

  • スマホ時:max(0px, (32 * (100vw / 780)))
  • PC時:max(12.8px, (24 * (100vw / 1400)))

max()関数は「カッコ内の値のうち、大きい方を使用する」という性質を持っているため、画面幅に合わせた「リキッドな可変」をさせつつ、同時に「最小値の設定」まで完結させることができます。

サイズ計算の基礎

リキッドレイアウトの計算の考え方はシンプルで、「デザイン全体の幅に対して、その要素がどれくらいの割合を占めるか」を算出するだけです。

計算式

( 要素のpx数 ÷ デザイン幅 ) × 100vw = 算出されるサイズ

例えば、デザイン幅が「1400px」で「16px」のサイズを指定したい場合は以下のようになります。

( 16 / 1400 ) * 100vw ≒ 1.14vw

.text {
  font-size: 1.14vw;
}

ただし、計算後の値を直接書くと、何から導き出した数値なのかが不明なため、保守性は良くありません。

.text {
  font-size: calc((16 / 1400) * 100vw);
}

これなら「1400px幅のデザインで16pxだった」という根拠が見て取れます。

しかし、すべての要素にこの長い式を書くのは冗長ですし、複雑な式を何度も記述するのはミスの原因にもなります。

記述をシンプルにするために計算の順序を入れ替え、共通部分をカスタムプロパティ(変数)として切り出します。

(元の式) (16 / 1400) * 100vw
(整理後) 16 * (100vw / 1400)

カスタムプロパティ化

これが、リキッドレイアウト計算における「基本の雛形」となります。

:root {
  /* 基準となる比率を定義 */
  --scale: (100vw / 1400);
}

.text {
  /* カンプの数値を掛けるだけ */
  font-size: calc(16 * var(--scale));
}
  1. 直感的: コードを見ただけで「16pxをスケーリングしている」とすぐ分かる。
  2. 正確: 面倒な小数点の計算はすべてブラウザに任せられる。
  3. 高保守性: デザイン幅が変わっても、1箇所変えるだけでサイト全体が即座に同期する。

このままでも使えますが、最小値を設定することで「極端な文字の縮小」を防ぐことができます。

最小値を設定

単純に流動的なフォントサイズにしてしまうと、デザインによってはブレイクポイント付近(800px付近など)で文字が小さくなり過ぎてしまう場合があります。

それを防ぐために、「最小値」を担保できる max()関数を利用します。

.text {
  /* 13pxの最小値を設定 */
  font-size: max(13px, (16 * var(--scale)));
}

ですが、このような書き方だと「32pxの見出しなら20pxまで」「40pxなら28pxまで」といった具合に、要素ごとに個別の最小値を計算して記述しなければなりません。

「何倍まで小さくするか」を決める

そこで、最小値をpxで指定するのではなく、「元のサイズの何倍まで下げて良いか」という倍率で定義します。

こうすることで、あらゆるサイズの文字に対して相対的に最小値を揃えることができます。

.text {
  /* 0.8倍以下にならないように設定 */
  font-size: max((16px * 0.8), (16 * var(--scale)));
}
  • 16pxの場合: 最小12.8pxまで可変
  • 40pxの場合: 最小32pxまで可変

この計算を効率よく使い回すために、共通部分を因数分解して整理します。

16 * max(0.8px, var(--scale))

この「16」以外の部分、つまりmax(0.8px, var(--scale))が、汎用的に使い回せるスケーリングの本体になります。

最小値を含めてカスタムプロパティ化

これまで解説してきた要素をすべて統合したのが、冒頭で紹介したこのカスタムプロパティです。

:root {
  /* PC用:1400px幅のデザイン基準。0.8倍(80%)を最小値として設定 */
  --scale: max(0.8px, (100vw / 1400));
}

.text {
  /* 16と書くだけで「可変」と「最小値12.8px」が適用される */
  font-size: calc(16 * var(--scale));
}

.title {
  /* 40と書くだけで「可変」と「最小値32px」が適用される */
  font-size: calc(40 * var(--scale));
}

最低値設定の考え方

最小値の倍率を「0px」にすると、常に相対値(可変側)の方が大きくなるため、制限なくどこまでも縮小させることができます。

/* 常に可変させる(下限なし) */
--scale: max(0px, (100vw / 1400));

逆に、ここを「1px」にすると、画面をどれだけ狭くしてもデザイン本来のサイズ(1倍)より小さくなることはありません。

/* 縮小させない(デザインサイズを維持) */
--scale: max(1px, (100vw / 1400));

最小値をいくつにするかは要件次第ですが、一つの目安として「PC環境での視認性」を基準にするのがおすすめです。

スマホであれば最悪の場合ピンチアウトで簡単に拡大できますが、PCではブラウザ自体のズーム機能を使わない限り、小さすぎる文字を読むのは困難だからです。

デザインと実用性のバランスを考えたら、本文13pxくらいが現実的な落としどころではないでしょうか。

「特定の画面幅以下」でサイズを固定したい場合は、「最小値としたい画面幅 ÷ デザイン幅」で算出した比率を指定すればOKです。

/* 画面幅960px以下でサイズ固定 */
--scale: max((960px / 1400), (100vw / 1400));

応用:最大値も同時に設定

応用で、clapm関数を使用すれば、最小値だけでなく「最大値」も同時に設定可能になります。

:root {
  /* 最小値, 相対値, 最大値; */
  --scale: clamp(0.8px, (100vw / 1400), 1px);
}

このように設定すると、画面幅が1400pxを超えても「任意の数値 x 1px」で固定されるため、指定の文字サイズより大きくなるのを防げます。

余白でも使える

カスタムプロパティに設定したのはあくまで「比率」なので、フォントサイズだけでなくpaddingmax-widthといった余白・サイズの指定にもそのまま活用できます。

/* カードのコンポーネント例 */
.card {
  max-width: calc(540 * var(--scale));
  padding: calc(24 * var(--scale));
  font-size: calc(28 * var(--scale));
}

使い方は同じく、デザインカンプ通りの数値を入力するだけで、余白も幅も、文字サイズと同期して可変します。

calc()の単位に注意

2026年5月現在、Firefoxでは calc(100vw / 1px) のような「単位同士の除算」に対応していません。

/* Firefoxでは無効になる */
font-size: calc(16px * (100vw / 1400px)); 

それ以外のブラウザであればcalc(1px * (比率)) が成立するため、remと組み合わせて「テキスト拡大」の両立ができます。

font-size: calc(1rem * (100vw / 1400px)); 

しかし、実際のブラウザでテストしてみると、Mac環境ではうまく動作するものの、iPhoneのSafariでは期待通り動作しませんでした。

いずれにせよ、現時点では従来通りremと使い分ける必要がありそうです。

/* デザイン維持:カンプ通りに可変させる */
.text {
  font-size: calc(16 * var(--scale));
}

/* 拡大対応(本文など) */
.content p {
  font-size: 1rem;
}

まとめ

コーディング効率と保守性を考えたら、カスタムプロパティでの管理がおすすめです。

実務で使用する際は、必要に応じて変数名を変更したり、使いやすい形にリファクタリングしてください。

カスタマイズに困ったらお気軽にご相談を!

  • 「ちょっとしたCSSの調整だけお願いしたい」
  • 「不具合を直してほしい」

料金は3,000円〜、お支払いは銀行振込・Amazonギフトカードなど柔軟に対応してます🤔

役に立ったら他の方にシェア

お気軽にコメントどうぞ

コメントする

目次