可変単位(vw, vh, rem, %)

vwvhremem%dvhsvhlvhcqwcqhcalc()

固定のpxではなく、画面サイズや親要素・フォントサイズに応じて変化する相対単位を使うことで、様々な環境に対応したレスポンシブなデザインを実現できます。

デモ:vw(ビューポート幅)

このバーの幅は 50vw(ビューポート幅の50%)です

50vw
100vw / 100vhビューポートの幅/高さ全体
50vwビューポート幅の半分
10vwビューポート幅の10%

デモ:em(複利)vs rem(常にルート基準)

em(親要素に依存)

親: 20px
子: 0.8em = 16px
孫: 0.8em = 12.8px(親の0.8→複利で小さくなる!)

rem(ルートhtml基準・安定)

親: 20px
子: 0.8rem = 12.8px(html基準)
孫: 0.8rem = 12.8px(同じ!親に無関係)

デモ:%(親要素の幅に対する割合)

width: 50%
width: 75%
width: 100%

デモ:vmin/vmax と calc()

20vmin
(小さい方の20%)
vmin: 幅・高さの小さい方
10vmax
(大きい方の10%)
vmax: 幅・高さの大きい方

calc() — calc(100% - 80px) で異なる単位を混在

width: calc(100% - 80px)

コード例

/* ビューポート単位 */
.hero    { height: 100vh; }   /* 画面高さいっぱい */
.sidebar { width: 20vw; }     /* 画面幅の20% */
.square  { width: 5vmin; height: 5vmin; } /* 短辺基準 */

/* フォント相対単位 */
.parent  { font-size: 20px; }
.em-child { font-size: 1.5em; }   /* 20px × 1.5 = 30px */
.rem-text { font-size: 1rem; }     /* htmlのfont-size × 1 (通常16px) */

/* % — 親要素に対する割合 */
.half     { width: 50%; }
.padding  { padding: 5%; }  /* 親の幅に対する割合 */
/* 注: height: % は親に高さが指定されている必要あり */

/* calc() — 異なる単位の計算 */
.sidebar   { width: calc(100% - 240px); }
.centered  { margin: 0 calc(50% - 300px); }
.fluid     { font-size: calc(16px + 1vw); }  /* 流体タイポグラフィ */

/* clamp() — 最小・推奨・最大値 */
.fluid-text { font-size: clamp(14px, 2vw, 22px); }
.container  { width: clamp(280px, 90%, 1200px); }

/* min() / max() */
.box { width: min(500px, 90%); }  /* 小さい方を採用 */
.bar { width: max(200px, 30%); }  /* 大きい方を採用 */

比較:em vs rem

観点emrem
基準直近の親要素の font-sizeルート要素(html)の font-size(通常16px)
継承⚠️ 入れ子で複利になる(バグの原因に)✅ 常に同じ基準(予測しやすい)
用途コンポーネント内のパディング・マージンフォントサイズ全般(アクセシビリティ◎)
アクセシビリティ△ ブラウザフォントサイズ設定の影響受けにくい✅ ユーザーのフォントサイズ設定を尊重
コンポーネント✅ 親に比例してスケールするので使いやすいことも✅ 予測可能で安定

NEWdvh/svh/lvh(モバイル対応)とコンテナクエリ単位(2022〜2023)

① dvh / svh / lvh — モバイルブラウザ問題を解決

スマートフォンのブラウザはアドレスバーが表示/非表示で高さが変わります。100vhだと隠れてしまう問題を解決する新単位です。

svh
Small Viewport Height
アドレスバーが出ている時の高さ(最小)
dvh
Dynamic Viewport Height
現在の実際の高さ(動的に変わる)
lvh
Large Viewport Height
アドレスバーが消えた時の高さ(最大)
/* 従来の問題: モバイルでアドレスバーが被る */
.hero { height: 100vh; } /* ❌ モバイルで隠れることがある */

/* 解決策 */
.hero { height: 100dvh; } /* ✅ 動的に調整(推奨) */
.safe-min { height: 100svh; } /* アドレスバーあり前提(常に見える) */
.safe-max { height: 100lvh; } /* アドレスバーなし前提 */

/* svw / dvw / lvw も同様に幅版がある */
.sidebar { width: 30dvw; }

② コンテナクエリ単位(cqw / cqh / cqi / cqb)

コンテナクエリと組み合わせて使う単位。ビューポートではなくコンテナ要素のサイズに対する割合です。

/* コンテナクエリ単位 (Chrome 105+, Firefox 110+, Safari 16+) */
.card-container {
  container-type: inline-size;
}

.card-title {
  /* コンテナの幅の5% — ビューポートではなくコンテナ基準 */
  font-size: 5cqw;
  padding: 2cqh 3cqi;
}

/* 単位一覧 */
/* cqw  — コンテナの幅の1% */
/* cqh  — コンテナの高さの1% */
/* cqi  — コンテナのインラインサイズの1% (横書きならcqwと同じ) */
/* cqb  — コンテナのブロックサイズの1% (横書きならcqhと同じ) */
/* cqmin — cqi と cqb の小さい方 */
/* cqmax — cqi と cqb の大きい方 */

dvh/svh/lvh: Chrome 108+, Firefox 101+, Safari 15.4+。cqw等: Chrome 105+, Firefox 110+, Safari 16+

🤖 AIプロンプトテンプレート

CSSの柔軟な単位(vw / vh / rem / em / % / clamp)を使ったレスポンシブデザインの実装例をReact + Tailwind CSSで作成してください。

要件:
- vw(ビューポート幅)・vh(ビューポート高さ)・svh(スモールビューポート)の違いと使い方
- rem(ルートフォントサイズ基準)と em(親フォントサイズ基準)の違いの比較デモ
- clamp() を使ったレスポンシブなフォントサイズ(clamp(1rem, 2.5vw, 2rem))の例
- % と vw の違い(コンテナ幅基準 vs ビューポート幅基準)
- dvh(dynamic viewport height)を使ったモバイルブラウザのアドレスバー対応例
- ウィンドウリサイズで各単位の変化をリアルタイムで確認できるデモ

各単位が画面サイズに応じてどう変化するかをリアルタイムで比較できるデモにしてください。

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。