CSSの主要単位は px(固定値)、rem(ルート基準の相対値)、em(親要素基準の相対値)、%(親要素の幅/高さ比)、vw/vh(ビューポート基準)の5種。font-sizeにはrem、コンポーネント内paddingにはem、レイアウト幅には%、全画面表示にはvw/vhが基本。clamp(min, preferred, max)を使えばメディアクエリなしで流体サイズを実現できる。
CSSの単位を理解する
CSSで使える長さの単位は大きく絶対単位と相対単位に分かれる。絶対単位はデバイスに関係なく常に同じサイズを表し、相対単位は基準となる値に応じて伸縮する。Web制作で実際に使うのは以下の6種+1関数がほぼ全てだ。
| 単位 | 種別 | 基準 | 代表的な用途 |
|---|---|---|---|
px |
絶対 | CSSピクセル(1/96インチ) | border, box-shadow, 細かい装飾 |
rem |
相対 | ルート要素(html)のfont-size | font-size, margin, padding |
em |
相対 | 親要素のfont-size | コンポーネント内の余白・アイコンサイズ |
% |
相対 | 親要素のサイズ | レイアウト幅, max-width |
vw |
相対 | ビューポートの幅(1vw = 1%) | 全幅セクション, ヒーローエリア |
vh |
相対 | ビューポートの高さ(1vh = 1%) | ファーストビュー, フルスクリーン |
clamp() |
関数 | 最小値・推奨値・最大値の3値 | 流体タイポグラフィ, レスポンシブ余白 |
ここからは各単位の特徴・適切な使い所・避けるべきケースを具体的なコードとともに見ていく。
px — いつ使うべきか
pxはCSSの絶対単位で、1pxは1/96インチ(CSSピクセル)に相当する。Retinaディスプレイでは1CSSピクセルが複数の物理ピクセルに対応するが、ブラウザがスケーリングを処理するためコード上は気にしなくていい。
pxを使うべき場面
pxが最適なのは「サイズが変わるべきではない」要素だ。ユーザーがブラウザのフォントサイズ設定を変更しても、ボーダーの太さや影の大きさまで比例して拡大してほしくはない。
pxを避けるべき場面
font-sizeにpxを使うとアクセシビリティ上の問題が生じる。ブラウザの「フォントサイズ設定」はルート要素のfont-sizeを変更する仕組みだが、pxで指定されたテキストはこの設定に反応しない。視覚障害のあるユーザーがフォントサイズを「大」に設定しても文字が大きくならないのだ。
Point
WCAG 2.2の達成基準1.4.4(テキストのサイズ変更)では、テキストを200%まで拡大してもコンテンツや機能が損なわれないことが求められている。font-sizeにpxを使うとこの基準を満たせない可能性がある。font-sizeには必ずremを使うのが現代の鉄則だ。
rem — フォントサイズと余白の基準
rem(root em)はルート要素(html)のfont-sizeを基準とする相対単位だ。ほとんどのブラウザでデフォルトのルートfont-sizeは16pxなので、1rem = 16px が基本の換算になる。
62.5%テクニック(非推奨)
古い記事で見かける html { font-size: 62.5%; }(1rem = 10pxにする方法)は、計算が楽になる反面、サードパーティのライブラリやブラウザのデフォルトスタイルが壊れるリスクがある。現在はブラウザの開発者ツールで換算を確認できるため、62.5%テクニックを使う必要はない。
remとpxの早見表
| rem | px(16px基準) | よくある用途 |
|---|---|---|
0.75rem |
12px | キャプション、注釈 |
0.875rem |
14px | 小さめの本文、ラベル |
1rem |
16px | 本文テキスト |
1.125rem |
18px | リード文 |
1.25rem |
20px | h4相当 |
1.5rem |
24px | h3相当 |
2rem |
32px | h2相当 |
2.5rem |
40px | h1相当 |
em — コンポーネント内の相対指定
emはその要素自身の(font-sizeプロパティ以外)または親要素の(font-sizeプロパティの場合)font-sizeを基準とする相対単位だ。remと名前が似ているが、基準が異なるため使い所がまったく違う。
emの強み: スケーラブルなコンポーネント
emの真価は「font-sizeを変えるだけでコンポーネント全体がスケールする」ことだ。ボタンの余白やアイコンサイズをemで指定しておけば、サイズバリエーション(small / medium / large)をfont-size一行で切り替えられる。
emの注意点: 入れ子の罠
emは累積する。font-size: 0.9emを指定したリストの中にさらにリストがあると、孫要素は0.9 × 0.9 = 0.81倍、ひ孫は0.9 × 0.9 × 0.9 = 0.729倍と、どんどん小さくなる。font-sizeの指定にはemではなくremを使うのが安全だ。
Point
emとremの使い分けは明快だ。font-sizeにはrem(ルート基準で予測しやすい)、padding・margin・border-radiusにはem(font-sizeに連動してスケール)。この2つを守れば大半のケースで困らない。
vw / vh — ビューポート基準の単位
vw(viewport width)とvh(viewport height)はブラウザの表示領域の幅・高さを基準とする単位だ。1vw = ビューポート幅の1%、1vh = ビューポート高さの1% になる。
vwをfont-sizeに使うリスク
font-size: 5vw のように指定すると、画面幅に完全に比例してフォントサイズが変わる。一見便利だが、超大画面では巨大に、超小画面では極小になり制御が効かない。さらに、ブラウザのフォントサイズ設定が無効化されるためアクセシビリティの問題も生じる。
100vhの罠(モバイルブラウザ)
モバイルブラウザでは、アドレスバーの表示/非表示で実際のビューポート高さが変動する。100vh はアドレスバーを含まない「大きいビューポート」を参照するため、アドレスバー表示時にコンテンツがはみ出す問題が長年あった。2023年以降、この問題を解決する新しい単位が追加されている。
| 単位 | 説明 | サポート状況 |
|---|---|---|
svh |
Small Viewport Height(アドレスバー表示時の高さ) | Chrome 108+ / Safari 15.4+ |
lvh |
Large Viewport Height(アドレスバー非表示時の高さ) | Chrome 108+ / Safari 15.4+ |
dvh |
Dynamic Viewport Height(リアルタイムで変動) | Chrome 108+ / Safari 15.4+ |
% — 親要素に対する相対値
% は親要素のサイズを基準とする相対単位だ。ただし、何に対する%なのかはプロパティによって変わる——ここが%の最大の落とし穴になる。
| プロパティ | 基準 | 例 |
|---|---|---|
width |
親要素の幅 | width: 50% → 親の幅の半分 |
height |
親要素の高さ | 親にheightが明示されていないと効かない |
padding |
親要素の幅(上下paddingも幅が基準) | padding-top: 56.25% → 16:9アスペクト比 |
margin |
親要素の幅(上下marginも幅が基準) | margin: 0 auto → 中央寄せ |
font-size |
親要素のfont-size | emと同じ動作(累積する) |
transform: translate |
自分自身のサイズ | translateX(-50%) → 自身の幅の半分左に |
Point
padding-top や padding-bottom に % を指定すると、基準は親の幅(高さではない)になる。これは仕様通りの動作で、かつてはアスペクト比の維持に利用されていた。現在は aspect-ratio プロパティが全モダンブラウザでサポートされているため、そちらを推奨する。
clamp() — 流体タイポグラフィの実装
clamp(最小値, 推奨値, 最大値)は3つの値を取るCSS関数で、推奨値が最小値〜最大値の範囲に収まるよう制約する。メディアクエリを書かずにビューポート幅に応じてフォントサイズや余白を流体的に変化させるために使う。2026年現在、全モダンブラウザ(対応率96%超)でサポート済みだ。
推奨値の計算方法
推奨値(preferred value)には vw + rem の形式を使うのがベストプラクティスだ。vw単独だとブラウザのフォントサイズ設定が無効化されるが、remを加算すると設定に部分的に反応する。
clamp()でメディアクエリを削減する
従来のレスポンシブ対応では、ブレイクポイントごとにfont-sizeやpaddingを切り替える必要があった。clamp()を使うと1行で済み、しかもブレイクポイント間の滑らかな変化が得られる。
ツールで効率化
clamp()の値を手計算するのは面倒だ。当サイトのCSS clamp()ジェネレーターなら、最小・最大のfont-sizeとビューポート幅を入力するだけで最適なclamp()式を自動生成できる。登録不要・完全無料。
場面別の使い分け早見表
最後に、プロパティ×単位の組み合わせを早見表にまとめた。迷ったらこの表を参照してほしい。
| プロパティ | 推奨単位 | 理由 |
|---|---|---|
font-size |
rem / clamp() |
アクセシビリティ(ブラウザ設定に連動)+ レスポンシブ |
line-height |
単位なし(1.5等) |
font-sizeの倍率として動作。emや%だと入れ子で崩れやすい |
padding / margin |
rem / em |
remで全体統一、emでコンポーネント内スケール |
width(レイアウト) |
% / fr |
親要素やグリッドコンテナーに対する比率 |
max-width |
px / rem |
「この幅を超えない」という絶対的な上限 |
height(フルスクリーン) |
dvh / svh |
モバイルのアドレスバー問題を回避 |
border |
px |
線の太さはフォント拡大で変わるべきではない |
border-radius |
px / em |
固定ならpx、コンポーネントと連動させるならem |
box-shadow |
px |
影の広がりは固定サイズが自然 |
gap(Grid/Flex) |
rem / clamp() |
全体の余白設計と統一。レスポンシブならclamp() |
| メディアクエリ | px |
ビューポートの物理サイズに対する閾値 |
Point
line-heightは単位なしの数値(例: 1.5)で指定するのがベストプラクティスだ。line-height: 1.5em や line-height: 150% は計算値が固定されて子要素に継承されるため、font-sizeが異なる子要素で行間が崩れる。単位なしなら常にfont-sizeの倍率として再計算される。