株式会社アスタスタ
WEB技術

CSSで使われる単位を復習してみる

Webエンジニア S.S.

2026.7.1

FigmaMCP活用で爆速コーディングじゃいという波がきていましたが、
いやいやデータがちゃんと綺麗に作られてないと難しいよ…とか、
デザイナーさんの力も借りないと…とか、
でもデザイナーさんはデザインをする専門家だしな…とか、
いろいろ思うわけです。心が3つある。

デザイナーさんにWeb系の話をした時に「へえ〜そうなんだ!」と思ってもらえそうなライトな内容ってなんだろうと考えた時に、単位はどうだろうかと思いまして。
社内で軽く喋ってみたところちょっとだけ好評だったので、ここにも書いてみたいと思います。

1. 「絶対単位」と「相対単位」がある

小難しくなってしまうとつまらなくなってしまうので、端的に。

  • 「絶対単位」
    構造・閲覧環境・画面サイズが何だろうが変化しません。
    10pxと書いたら必ず10pxになります。

  • 「相対単位」
    親要素などの基準になるものに対して相対的に算出された数値になります。
    後ほどでてきますが、たとえば 2em と書いたら親要素の2倍の値になります。

2. おなじみの単位たち

【 px(ピクセル)】

構造・閲覧環境・画面サイズが何だろうが変化しない単位。

HTML

<div class="parent-px">
  親要素:フォントサイズは16px
  <p class="child-px">子要素:フォントサイズは32px</p>
</div>

CSS

.parent-px {
  font-size: 16px;
}
.child-px {
  font-size: 32px;
}

【 em(エム)】

親要素のフォントサイズを「1」として数値を出す単位。

HTML

<div class="parent-em">
  親要素:フォントサイズは16px
  <p class="child-em">子要素:フォントサイズは32px、paddingは32px</p>
</div>

CSS

.parent-em {
  font-size: 16px;
}

.child-em {
  font-size: 2em; /* 16px × 2 = 32px */
  padding: 1em;   /* font-size = 32px */
}

【 rem(レム/ルートエム】

親要素が何pxであっても関係なく、常にルート要素(通常は<html>)のフォントサイズを基準にする単位。
(ブラウザのデフォルトは基本16px)。

HTML

<div class="parent-rem-default">
  親要素:フォントサイズは24px
  <p class="child-rem-default">
    子要素:フォントサイズは32px、paddingは16px
  </p>
</div>

CSS

.parent-rem-default {
  font-size: 24px;
}

.child-rem-default {
  font-size: 2rem; /* ブラウザの設定(基本は16px)× 2 = 32px */
  padding: 1rem;   /* ブラウザの設定(基本は16px)× 1 = 16px */
}

(↓html要素にフォントサイズ指定がある場合の例)

HTML

<div class="parent-rem-ex">
  親要素:フォントサイズは24px
  <p class="child-rem-ex">
    子要素:フォントサイズは28px、paddingは14px
  </p>
</div>

CSS

html {
  font-size: 14px; /* 基準を「14px」に固定した場合 */
}

.parent-rem-ex {
  font-size: 24px;
}

.child-rem-ex {
  font-size: 2rem; /* 14px × 2 = 28px */
  padding: 1rem;   /* 14px × 1 = 14px */
}

【 %(パーセント)】

横幅(width)や余白(padding)などに使う場合は「親要素コンテンツの横幅サイズ」が基準になる単位。
※文字サイズ(font-size)に使う場合は em と同じ

HTML

<div class="parent-pct">
  親要素:横幅は900px、高さは300px、フォントサイズは20px
  <div class="child-pct">
    子要素:横幅は630px、paddingは45px、フォントサイズは18px
  </div>
</div>

CSS

.parent-pct {
  width: 900px;
  height: 300px;
  font-size: 20px;
}

.child-pct {
  width: 70%;     /* 900px × 70% = 630px */
  padding: 5%;    /* 900px × 5% = 45px  */
  font-size: 90%; /* 20px × 90% = 18px */
}

【 cqw/cqh(コンテナクエリ・ウィズ/ハイト)】

「特定の親要素(親コンテナ)」を基準にできる単位。
(モーダルで大活躍)

  • cqw: 親コンテナの幅の1%

HTML

<div class="container-parent-cqw">
  親コンテナ:横幅は900px、高さは300px
  <p class="container-child">
    子要素:フォントサイズは45px、paddingは9px
  </p>
</div>

CSS

.container-parent-cqw {
  width: 900px;
  height: 300px;
  container-type: inline-size; /* この要素を親コンテナに設定(幅基準) */

  .container-child {
    padding: 1cqw;   /* 900px × 1% = 9px */
    font-size: 5cqw; /* 900px × 5% = 45px */
  }
}

  • cqh: 親コンテナの高さの1%

HTML

<div class="container-parent-cqh">
  親コンテナ:横幅は900px、縦幅は300px
  <p class="container-child">
    子要素:フォントサイズは15px、paddingは3px
  </p>
</div>

CSS

.container-parent-cqh {
  width: 900px;
  height: 300px;
  container-type: size; /* この要素を親コンテナに設定(幅と高さ基準) */

  .container-child {
    padding: 1cqh;    /* 300px × 1% = 3px */
    font-size: 5cqh; /* 300px × 5% = 15px */
  }
}

3. ビューポート(画面サイズ)が基準になる単位たち

【 vw/vh (ビューポート・ウィズ/ハイト)】

画面サイズの「横幅いっぱい」と「高さいっぱい」が基準になる単位。

※現在、なにもしないと「横幅いっぱい」にはスクロールバー分が含まれますが、scrollbar-gutter: stableをルートに指定しておくとスクロールバー分は含まれなくなりました。

  • vw: 画面サイズの横幅いっぱいの1%

  • vh: 画面サイズの高さいっぱいの1%

(↓画面サイズが「横 375px × 縦 667px」の場合の例)

HTML

<div class="box-vw">横幅は187.5px</div>
<div class="box-vh">高さは333.5px</div>

CSS

/* 例:画面が「横 375px × 縦 667px」の場合 */

.box-vw {
  width: 50vw;  /* 375px × 50% = 187.5px */
}
.box-vh {
  height: 50vh; /* 667px × 50% = 333.5px */
}

vhは今までアドレスバー・ナビゲーションバーによる呪いなどたくさんの躓きがあり、JavaScriptで調整する時代がありました。
この呪いによる原因は「画面サイズの高さ」が変わる事でしたが、以下の3つの単位のおかげでとても楽になりました。

【 svh/lvh/dvh(動的ビューポート)】

画面サイズの「高さいっぱい」が基準になる単位、の動的バージョン。
(横幅版のsvw、lvw、dvwもありますが、ほぼ同じなので割愛)

  • svh(Small Viewport Height):

    アドレスバーが「表示されている(一番狭い)」ときの画面の高さの1%
    →画面内に確実にコンテンツを収めたい(要素が下部に隠れてほしくない)時に便利

  • lvh(Large Viewport Height):
    アドレスバーが「引っ込んでいる(一番広い)」ときの画面の高さの1%
    vhと基本的に同じ

  • dvh(Dynamic Viewport Height):
    アドレスバーの開閉に合わせて「リアルタイムに変化する」画面の高さの1%
    →アドレスバーが出ているときは自動で縮み、引っ込んだら自動で伸びていく

dvhはこの特性上、サイトの構造によってはアドレスバーが開閉するたびに画面がカクカク動いたりするようになりますので、注意が必要です。
閲覧しているユーザー側はカクカクが気になってレイアウトシフトが発生しているように感じるかもしれないですが、Google的にはレイアウトシフトとしては認識されないと聞きました。アクセシビリティには影響がないそうですが、結果的にクリックミスなどを起こすので気をつけたいところです。

「ここは画面の高さいっぱいで!」という指示に深みが増しますね。よく確認するようにしましょう。

【 vmax/vmin(ビューポート・最大/最小) 】

画面サイズ縦横の、大きい方or小さい方が基準になる単位。

  • vmax: 画面の「縦」と「横」を比べて、長い方の1%

  • vmin: 画面の「縦」と「横」を比べて、短い方の1%

(↓画面サイズが「横 900px × 縦 600px」の場合の例)

HTML

<div class="box-vmax">横幅は450px</div>
<div class="box-vmin">横幅は300px</div>

CSS

/* 例:画面が「横 900px × 縦 600px」の場合 */

.box-vmax {
  width: 50vmax; /* 900px(長い方) × 50% = 450px */
}
.box-vmin {
  width: 50vmin; /* 600px(短い方) × 50% = 300px */
}

4. 番外編:こんな単位もあるんです

【 lh(ライン・ハイト) 】

文字サイズ(font-size)ではなく、その要素に設定されている「1行分の高さ(line-height)」を「1」として数値を出す単位。

例えば、よくある「NEW」の高さを1行分と同じにしたい、時などに使えそうです。

HTML

<hgroup class="parent-lh">
  <span class="badge-lh">NEW</span>
  <h2 class="title-lh">
    ダミータイトル
  </h2>
</hgroup>
<p>ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</p>

CSS

.parent-lh {
  display: flex;
  line-height: 1.5; /* 1行の高さは 16px × 1.5 = 24px */ 
}
.title-lh {
  padding: 0;
  font-size: 16px;
  font-weight: bold;
}
.badge-lh {
  display: inline-block;
  height: 1lh;      /* 1行の高さ(24px)と完全に一致する */

  margin-right: 0.5em;
  padding: 0 0.5em;
  color: #fff;
  font-weight: bold;
  background-color: #FC18C4;
}

【 rlh(ルート・ライン・ハイト) 】

常に「ルート要素(通常は<html>)の1行分の高さ(line-height)」を基準にする単位。

例が難しいですが、remの行間バージョン。何か役に立つかもしれない。

HTML

<div class="card-rlh">
  <h2 class="title-rlh">見出し:行間は1.2</h2>
  <p>
    ダミーテキスト:行間は1.5(ルート基準)<br>
    ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト
  </p>
</div>

CSS

html {
  font-size: 16px;  /* 例として基準を「16px」としておく */
  line-height: 1.5; /* ルートの1行の高さは 16px × 1.5 = 24px (これが1rlh) */
}

.card-rlh {
  padding: 2rlh;    /* 24px × 2 = 48px (本文の「2行分」の余白を正確に取れる) */
}

.title-rlh {
  font-size: 32px;  /* 例として文字を大きく */
  line-height: 1.2; /* この要素の1lhは 32 × 1.2=38.4px となるがrlhには影響しない */

  margin-bottom: 1rlh; /* ルート基準 = 24px */
}

まだまだたくさんあります。勉強し続けたいと思います。

まとめ

今回の趣旨としましては「たくさんあるんだな〜」とちょっとだけ興味を持ってもらえたら嬉しいな、という気持ちです。
全部覚えるのはコーディングをする人ですが、きっとデザイナーさんが覚えてもバイブコーディングなどなどでなにかと役に立つのではないかなと感じます。

最近、Studioでdvhが使えると知りました。動的に変わってくれるので便利ですが、ちょっとだけ落とし穴がありますので、気をつけつつ乗り越えていけるといいなと思います。
最後まで読んでいただき、ありがとうございました。

share

関連する記事

この人が書いた記事