レスポンシブデザイン

画面サイズに応じてレイアウトを自動調整し、あらゆるデバイスで最適な表示を実現する手法

CSSUI

レスポンシブデザインとは

レスポンシブデザイン (Responsive Design) は、CSS メディアクエリと柔軟なレイアウトで、画面サイズ (スマートフォン、タブレット、デスクトップ) に応じて表示を自動調整する手法である。Ethan Marcotte が 2010 年 5 月 25 日の A List Apart 誌 (Issue 306) の記事で提唱した用語で、当初から ①フルードグリッド (幅を割合で持つ格子) ②フレキシブルイメージ (枠に収まるよう伸縮する画像) ③メディアクエリ の 3 点セットとして定義されている。画面ごとに別の URL とマークアップを用意する分離型と違い、1 つの HTML を CSS 側で組み替える点が本質である。

viewport メタタグ

モバイルブラウザーは、モバイル非対応のページが崩れないように、既定では仮想的な広いビューポート (おおむね 980px 幅) でレイアウトしてから画面幅に縮小して表示する。この縮小が効いている間はメディアクエリも仮想幅で判定されるため、CSS を書いてもレイアウトが切り替わらない。width=device-width はレイアウト幅を実機の幅に一致させ、この縮小をやめさせる指定である。

<meta name="viewport" content="width=device-width, initial-scale=1" />

user-scalable=nomaximum-scale=1 でズームを禁じると、弱視の利用者が文字を拡大できなくなる。iOS 10 以降はこれらの指定を既定で無視するため、書いても得るものがない。

メディアクエリ

メディアクエリは条件に合う間だけ宣言を有効にする。下の例のようにモバイル向けを素の宣言に置き、min-width で上へ足していくと、同じ詳細度のまま後の規則が前を上書きする形になり、打ち消し用の max-width を書かずに済む。

/* モバイルファースト: 小さい画面をデフォルトに */
.container { padding: 1rem; }

/* タブレット以上 */
@media (min-width: 768px) {
  .container { padding: 2rem; max-width: 768px; margin: 0 auto; }
}

/* デスクトップ */
@media (min-width: 1024px) {
  .container { max-width: 1200px; }
}

ブレークポイント

ブレークポイントは特定機種の実寸に合わせるのではなく、ウィンドウを実際に狭めながらレイアウトが破綻する幅 (文字が詰まる、カードが潰れる) を探して決める。以下は Tailwind CSS の既定値を目安として並べたもので、2026 年 8 月時点の既定は rem 基準のため括弧内にルート 16px 換算を添えた。

デバイスTailwind
モバイル< 640pxデフォルト
横向きスマートフォン≥ 640px (40rem)sm:
タブレット≥ 768px (48rem)md:
デスクトップ≥ 1024px (64rem)lg:
ワイド≥ 1280px (80rem)xl:
特大≥ 1536px (96rem)2xl:

Flexbox + Grid

段数を画面幅ごとに指定したいなら Flexboxflex-wrap で足りる。列の幅を保ったまま段数の決定をブラウザーに任せたい一覧は Grid の auto-fit が向く。

/* Flexbox: 1列 → 3列 */
.cards { display: flex; flex-wrap: wrap; gap: 1rem; }
.card { flex: 1 1 100%; }
@media (min-width: 768px) { .card { flex: 1 1 calc(33.3% - 1rem); } }

/* Grid: auto-fit で自動調整 */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem; }

minmax(300px, 1fr) は下限が固定値なので、コンテナ幅が 300px を下回ると 1 列でも横にはみ出す。狭い画面や入れ子の内側で使うなら minmax(min(300px, 100%), 1fr) として、下限をコンテナ幅で頭打ちにする。

レスポンシブ画像

srcsetw 記述子は画像の実ピクセル幅の申告にすぎず、どれを使うかはブラウザーが sizes から求めた表示幅と画面の解像度から決める。sizes を省くと表示幅は 100vw とみなされるため、半分の幅で置く画像に過大なファイルが選ばれる。

<!-- srcset で画面サイズに応じた画像を配信 -->
<img
  src="photo-800.webp"
  srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1200.webp 1200w"
  sizes="(max-width: 768px) 100vw, 50vw"
  alt="Photo"
/>

Container Queries

メディアクエリはビューポート幅に基づくが、Container Queries は親コンテナの幅に基づく。主要ブラウザーで揃ったのは 2023 年 2 月で、2026 年 8 月時点では前提にして差し支えない。同じカード部品をサイドバーと本文の両方に置く場合、ビューポート幅では両者を区別できないが、コンテナ幅なら置き場所に応じて自動で切り替わる。

.card-container { container-type: inline-size; }

@container (min-width: 400px) {
  .card { display: flex; }
}

モバイルファースト vs デスクトップファースト

どちらから書き始めるかで、追加する宣言と打ち消す宣言のどちらが増えるかが変わる。

アプローチメディアクエリ推奨
モバイルファーストmin-width基本はこちら (モバイルからの流入が多い)
デスクトップファーストmax-width管理画面など

テスト

Chrome DevTools のデバイスモードで各画面サイズを試せるが、再現できないものが 2 つある。1 つはアドレスバーの伸縮で、100vh は URL バーが隠れた状態の高さ (lvh と同値) を指すため、実機では画面の下がはみ出す。伸縮に追従させたい高さには dvh を使う。もう 1 つは指の当たり判定で、隣り合うボタンの間隔が足りているかは実機で触るまで分からない。

選び分けの目安として、要素の並べ替えや表示・非表示の切り替えで済むならメディアクエリで足り、同じ部品を複数の置き場所で使い回すならコンテナクエリを選ぶ。画面幅ごとに別の HTML を返す作りは URL とマークアップが二重になり、片方だけ更新されて内容がずれる事故が起きやすいため、最後の手段とする。

この記事は役に立ちましたか?

関連用語

関連する記事