レスポンシブデザイン入門 — メディアクエリ・モバイルファースト・clamp()の使い方
この章の目次開く
- まず必須 — viewport メタタグ
- メディアクエリの基本
- モバイルファースト vs デスクトップファースト
- モバイルファースト — まずスマホ向けを書き、min-width で拡張
- デスクトップファースト — まずPC向けを書き、max-width で絞る
- ブレークポイントの選び方
- 相対単位の活用 — メディアクエリに頼りすぎない
- clamp() — メディアクエリ不要のレスポンシブ値
- レスポンシブでよく使うパターン
- コンテナの最大幅 + 左右余白
- 画像をはみ出させない
- ナビゲーションの切り替え
- よくあるハマりどころ
- メディアクエリの順番で上書きされる
- ブレークポイントが1px重なる
- ちゃんと使うためのポイント
- 参考リンク
スマートフォン・タブレット・PCなど、様々な画面サイズでも適切に表示されるデザインをレスポンシブデザインと呼びます。CSSではメディアクエリを使って、画面幅に応じてスタイルを切り替えます。
学習者PCで作ったページをスマホで見たら崩れてた…。画面サイズごとにどう対応すればいいの?
レスポンシブデザインの鍵は3つです。viewport メタタグ、メディアクエリ、そして相対単位の活用。順番に見ていきましょう。

まず必須 — viewport メタタグ
HTMLの <head> に以下がないと、スマートフォンでメディアクエリが正しく機能しません。
<meta name="viewport" content="width=device-width, initial-scale=1">これがないと、スマートフォンは「このページはPC用だ」と判断し、980px幅(など)で描画してから画面に縮小表示します。結果、メディアクエリの min-width: 768px が「常に条件を満たす」ことになり、スマホ向けスタイルが当たらなくなります。
メディアクエリの基本
@media ルールの中に書いたスタイルは、条件に一致するときだけ適用されます。
/* 768px以上の画面幅のとき */
@media (min-width: 768px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}構文: @media (条件) { ...スタイル }
| 条件 | 意味 | 使い所 |
|---|---|---|
min-width: 768px | 768px以上のとき | モバイルファーストで大画面を拡張 |
max-width: 767px | 767px以下のとき | デスクトップファーストでスマホを制限 |
prefers-color-scheme: dark | ダークモードのとき | テーマ切り替え |
prefers-reduced-motion: reduce | アニメーション抑制設定のとき | アクセシビリティ対応 |
複数の条件を組み合わせることもできます。
/* 768px以上 かつ 1024px以下 → タブレットだけ */
@media (min-width: 768px) and (max-width: 1024px) {
.sidebar { display: none; }
}モバイルファースト vs デスクトップファースト
学習者min-width と max-width、どっちを使えばいいの?混在すると頭がこんがらがるんだけど…。
モバイルファースト(min-width を使う)が現在の主流です。理由を見てみましょう。
モバイルファースト — まずスマホ向けを書き、min-width で拡張
/* デフォルト:スマートフォン向け */
.grid {
display: grid;
grid-template-columns: 1fr; /* 1列 */
gap: 16px;
}
/* タブレット以上:2列 */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* PC以上:3列 */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}デスクトップファースト — まずPC向けを書き、max-width で絞る
/* デフォルト:PC向け */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
/* タブレット以下:2列 */
@media (max-width: 1023px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* スマホ以下:1列 */
@media (max-width: 767px) {
.grid {
grid-template-columns: 1fr;
}
}
先生モバイルファーストの方がCSSが短く済むことが多いよ。スマホ=最もシンプルな状態をベースにして、大画面で「足す」方が、大画面の複雑なレイアウトを小画面で「削る」より素直なんだ。
ブレークポイントの選び方
画面幅でスタイルが切り替わる境界値をブレークポイントと呼びます。プロジェクトで統一するのが重要です。
| 名前 | 幅 | 対象 |
|---|---|---|
| sm | 640px | 大きめのスマートフォン |
| md | 768px | タブレット |
| lg | 1024px | ノートPC |
| xl | 1280px | デスクトップ |
| 2xl | 1536px | 大画面 |
実務では2〜3個のブレークポイントで十分なことがほとんどです。
/* 最小構成の例 */
/* スマホ → デフォルト */
/* タブレット以上 → @media (min-width: 768px) */
/* PC以上 → @media (min-width: 1024px) */相対単位の活用 — メディアクエリに頼りすぎない
メディアクエリは強力ですが、すべてをブレークポイントで切り替えていると管理が大変になります。相対単位を使えば、メディアクエリなしで自然にレスポンシブになる部分が増えます。
| 単位 | 意味 | 用途 |
|---|---|---|
% | 親要素に対する割合 | 幅の指定 |
vw / vh | ビューポートの幅 / 高さの1% | ヒーローセクションの高さなど |
rem | ルート要素(html)のfont-sizeの倍数 | 余白・フォントサイズ |
em | 親要素のfont-sizeの倍数 | コンポーネント内の相対サイズ |
clamp() — メディアクエリ不要のレスポンシブ値
clamp(最小値, 推奨値, 最大値) で、画面幅に応じて値を滑らかに変化させられます。
h1 {
/* 最小1.5rem、推奨4vw、最大3rem */
font-size: clamp(1.5rem, 4vw, 3rem);
}
.container {
/* 最小320px、推奨90%、最大1200px */
width: clamp(320px, 90%, 1200px);
margin: 0 auto;
}
.section {
/* 余白もレスポンシブに */
padding: clamp(16px, 4vw, 64px);
}
先生clamp() はレスポンシブデザインの革命的な関数だよ。メディアクエリで3段階に切り替えていたフォントサイズが、1行で滑らかに変化するようになる。
レスポンシブでよく使うパターン
コンテナの最大幅 + 左右余白
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0 16px;
}max-width + width: 100% の組み合わせは最も基本的なレスポンシブパターンです。PC では中央寄せ、スマホでは全幅になります。
画像をはみ出させない
img {
max-width: 100%;
height: auto;
}画像が親要素からはみ出すのを防ぎつつ、アスペクト比を保ちます。リセットCSSやフレームワークに含まれていることも多いですが、素のCSSでは必ず指定しましょう。
ナビゲーションの切り替え
/* スマホ:ハンバーガーメニュー用 */
.nav-links { display: none; }
.hamburger { display: block; }
/* PC:横並びナビ */
@media (min-width: 768px) {
.nav-links {
display: flex;
gap: 24px;
}
.hamburger { display: none; }
}
よくあるハマりどころ
メディアクエリの順番で上書きされる
/* ❌ lg → md の順で書くと、md が lg を上書きしてしまう */
@media (min-width: 1024px) { .box { width: 33%; } }
@media (min-width: 768px) { .box { width: 50%; } } /* 1024px以上でもこれが適用 */
/* ⭕ 小さい順に書く */
@media (min-width: 768px) { .box { width: 50%; } }
@media (min-width: 1024px) { .box { width: 33%; } }min-width のモバイルファーストでは、小さい値から大きい値の順に書きます。CSSは同じ詳細度なら後に書いた方が勝つため、順番が重要です。
ブレークポイントが1px重なる
/* ❌ 768pxのとき両方にマッチする */
@media (max-width: 768px) { ... }
@media (min-width: 768px) { ... }
/* ⭕ モバイルファーストなら min-width だけで統一 */
/* デフォルト → スマホ */
@media (min-width: 768px) { ... } /* タブレット以上 */min-width と max-width を混在させると境界値の1pxで意図しない重複が起きやすくなります。モバイルファーストに統一するのが安全です。
ちゃんと使うためのポイント
-
viewportメタタグは必須。これがないとスマホでメディアクエリが機能しない min-widthでモバイルファーストに書くのが保守しやすい(小さい順に並べる)- ブレークポイントはプロジェクト内で統一する(Tailwindの値が参考になる)
clamp()や%・remなどの相対単位を活用し、メディアクエリに頼りすぎないauto-fill + minmax(前章のCSS Grid)を使えば、カードグリッドはメディアクエリ不要
次の章では、読みやすいテキストを作るタイポグラフィとフォントのスタイリングを学びます。
参考リンク
- MDN — メディアクエリーの使用 — メディアクエリの使い方の公式ガイド
- MDN — レスポンシブデザイン — レスポンシブデザインの学習ガイド
- MDN — clamp() —
clamp()関数のリファレンス - MDN — viewport — viewportメタタグの公式仕様
