CSS の単位の使い分け - px, rem, em, vw, % の判断基準

CSS には多くの長さの単位があり、同じ見た目を実現するにも複数の書き方が存在します。チーム開発で「ここは px なのか rem なのか」と迷うたびに判断がブレると、プロジェクト全体の一貫性が崩れていきます。単位ごとの特性を理解し、用途に応じた使い分けの基準を持っておくことが重要です。

px - 絶対値が必要な場面で使う

px は画面上のピクセル数を直接指定する単位です。ユーザーのフォントサイズ設定やビューポートの大きさに影響されず、常に同じ値を維持します。

.border-card {
  border: 1px solid #ccc;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

ボーダーやシャドウのように、フォントサイズに連動して太くなったり広がったりする必要がない装飾には px が適しています。逆に、フォントサイズやパディングに px を多用すると、ブラウザのフォントサイズ設定を変更しても文字が大きくならず、アクセシビリティ上の問題を引き起こします。

px が適切な用途

ボーダー幅、ボックスシャドウのオフセットやぼかし、アウトライン、ごく小さな装飾的スペーシングなど、物理的なサイズが固定であるべき要素。

px を避けるべき用途

font-size、line-height、padding、margin など、ユーザーの設定に応じて拡縮すべきプロパティ。

rem - フォントサイズとスペーシングの基本単位

rem はルート要素(<html>)の font-size を基準とする相対単位です。ブラウザのデフォルトでは <html> の font-size は 16px なので、1rem = 16px として計算されます。

html {
  font-size: 16px; /* ブラウザデフォルトと同じ */
}

.heading {
  font-size: 1.5rem; /* 24px */
  margin-bottom: 1rem; /* 16px */
}

.body-text {
  font-size: 1rem; /* 16px */
  line-height: 1.5; /* 単位なし = フォントサイズの1.5倍 */
}

rem の最大の利点は、ルートの font-size を変えるだけでサイト全体のスケーリングが一括で変わる点にあります。ユーザーがブラウザの設定でフォントサイズを大きくした場合にも、rem で指定した値はすべて連動して拡大されます。

font-size だけでなく、padding や margin にも rem を使うと、フォントサイズの変更に合わせて余白も比例して広がるため、レイアウトのバランスが保たれます。

em - 親要素に連動させたい場面で使う

em は「その要素自身の font-size」を基準とする相対単位です。ただし font-size プロパティに em を指定した場合は「親要素の font-size」が基準になります。この二重の基準がしばしば混乱を招きます。

.parent {
  font-size: 16px;
}

.parent .child {
  font-size: 1.25em; /* 親の 16px × 1.25 = 20px */
  padding: 1em;      /* 自身の 20px × 1 = 20px */
}

em はネストすると基準値が変わっていくため、深い階層構造で使うと計算が複雑になります。

.level-1 {
  font-size: 1.2em; /* 16px × 1.2 = 19.2px */
}

.level-1 .level-2 {
  font-size: 1.2em; /* 19.2px × 1.2 = 23.04px */
}

.level-1 .level-2 .level-3 {
  font-size: 1.2em; /* 23.04px × 1.2 = 27.648px */
}

この累積効果(compounding)があるため、font-size に em を使うのは限定的な場面に留め、基本的には rem を使うほうが安全です。

em が有効な場面

ボタンの padding をフォントサイズに比例させたい場合など、「その要素自身の文字の大きさ」に連動させたいプロパティに使う。

em を避けるべき場面

font-size の指定に em を使うと、ネスト階層が深くなるにつれて意図しないサイズの累積が起きる。

em の良い使い方として、コンポーネント内の余白をフォントサイズに連動させるパターンがあります。

.button {
  font-size: 1rem;
  padding: 0.5em 1em; /* フォントサイズに比例した余白 */
}

.button-large {
  font-size: 1.25rem;
  /* padding は em なので自動的に拡大される */
}

この書き方なら、font-size を変えるだけでボタン全体のサイズが比例して変わります。

vw と vh - ビューポート基準の単位

vw(viewport width)と vh(viewport height)は、ブラウザの表示領域を基準とする単位です。1vw はビューポート幅の 1% に相当します。

.hero {
  height: 100vh;
  font-size: clamp(1rem, 2.5vw, 3rem);
}

vw をフォントサイズに直接使うと、ビューポート幅に比例して文字が際限なく大きくなったり小さくなったりします。clamp() 関数と組み合わせて最小値と最大値を制限するのが実用的な書き方です。

モバイルブラウザでは URL バーの表示・非表示によって 100vh の実際の高さが変動し、コンテンツが隠れる問題がよく発生します。

この問題に対処するために dvh(dynamic viewport height)が導入されており、モダンブラウザでは 100dvh を使うほうが安定する。

/* モバイルブラウザで安定するフルスクリーン指定 */
.hero {
  height: 100dvh;
}

/* dvh 未対応ブラウザへのフォールバック */
@supports not (height: 100dvh) {
  .hero {
    height: 100vh;
  }
}

% - 親要素基準のサイズ指定

% は親要素のサイズを基準とする相対単位です。width に % を使えば親の幅に対する比率、padding に % を使えば親の幅に対する比率(上下の padding も親の幅が基準になる点に注意)として計算されます。

.container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.sidebar {
  width: 30%;
}

.main {
  width: 70%;
}

% はレイアウトの分割比率を表現するのに適しています。ただし、現在では Flexbox や Grid を使えば比率指定を % に頼る必要はほとんどありません。

/* % で比率を書く代わりに */
.layout {
  display: grid;
  grid-template-columns: 3fr 7fr;
}

fr 単位は Grid コンテナ内の空きスペースを比率で分配する単位で、% よりもギャップの計算を自動で処理してくれるため、レイアウトの分割には fr のほうが扱いやすい場面が多くあります。

単位なしの値が適切なプロパティ

一部のプロパティでは単位をつけないほうが望ましい動作をします。代表的なのは line-height です。

/* 単位なし — フォントサイズに対する倍率 */
.text {
  font-size: 1rem;
  line-height: 1.5; /* font-size × 1.5 = 24px */
}

/* em 指定 — 計算結果が子要素に継承される */
.text-em {
  font-size: 1rem;
  line-height: 1.5em; /* 24px という計算結果が継承される */
}
line-height: 1.5(単位なし)

各要素の font-size に対する倍率として継承されるため、フォントサイズが異なる子要素でも適切な行間が保たれる。

line-height: 1.5em

計算結果の絶対値(例: 24px)が継承されるため、フォントサイズが異なる子要素で行間が狭すぎたり広すぎたりする。

line-height には常に単位なしの値を使うことを規約にしておくと、継承による予期しない行間の問題を防げます。

判断基準の一覧

どのプロパティにどの単位を使うか迷ったときの判断基準をまとめます。

プロパティ推奨単位理由
font-sizeremユーザー設定に連動する
padding / marginremフォントサイズに比例した余白
border / shadowpx装飾は固定サイズが自然
プロパティ推奨単位理由
width(レイアウト)%, fr, auto親やグリッドに対する比率
height(全画面)dvh, vhビューポート基準
line-height単位なし継承時の挙動が安定する

コンポーネント内の padding を em にするかどうかはチームの方針次第ですが、「font-size は rem、それ以外のスペーシングも原則 rem、装飾は px」という基本方針を持っておけば、大半のケースで判断に迷うことはなくなります。