レスポンシブWebデザインとは
画面サイズに応じてレイアウトが変化するデザインです。
なぜ必要か
- 📱 モバイルからのアクセスが全体の60%超
- 🔍 GoogleのSEO評価(モバイルファースト)
- 💰 コンバージョン率向上
- 🌐 多様なデバイスへの対応
3つの基本技術
- ビューポート設定: 必須のメタタグ
- メディアクエリ: 画面サイズごとのCSS
- フレキシブルレイアウト: Flexbox/Grid
1. ビューポート設定
すべてのレスポンシブサイトに必須のメタタグです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>レスポンシブサイト</title>
</head>各パラメータの意味
width=device-width
→ 画面幅をデバイスの幅に合わせる
initial-scale=1.0
→ 初期ズーム倍率を100%に
maximum-scale=5.0
→ 最大ズーム倍率(アクセシビリティのため制限しすぎない)
user-scalable=yes
→ ユーザーによるズームを許可(デフォルト)2. メディアクエリ
画面サイズに応じてCSSを切り替えます。
基本的な書き方
/* モバイル(デフォルト) */
.container {
width: 100%;
padding: 1rem;
}
/* タブレット(768px以上) */
@media (min-width: 768px) {
.container {
width: 750px;
margin: 0 auto;
}
}
/* デスクトップ(1024px以上) */
@media (min-width: 1024px) {
.container {
width: 960px;
}
}
/* 大画面(1280px以上) */
@media (min-width: 1280px) {
.container {
width: 1200px;
}
}標準的なブレークポイント
/* スマートフォン */
320px - 最小(iPhone SE)
375px - 一般的(iPhone)
414px - 大型スマホ
/* タブレット */
768px - iPad縦
1024px - iPad横
/* デスクトップ */
1280px - 小型PC
1440px - 一般的PC
1920px - フルHD
2560px - 4K実装例:カードレイアウト
<!-- HTML -->
<div class="cards">
<div class="card">カード1</div>
<div class="card">カード2</div>
<div class="card">カード3</div>
<div class="card">カード4</div>
</div>
<!-- CSS -->
<style>
.cards {
display: flex;
flex-wrap: wrap;
gap: 1rem;
padding: 1rem;
}
.card {
background: white;
border: 3px solid #2a2a2a;
padding: 2rem;
box-shadow: 4px 4px 0px rgba(0,0,0,0.1);
flex: 1 1 100%; /* モバイル: 1列 */
}
/* タブレット: 2列 */
@media (min-width: 768px) {
.card {
flex: 1 1 calc(50% - 0.5rem);
}
}
/* デスクトップ: 4列 */
@media (min-width: 1024px) {
.card {
flex: 1 1 calc(25% - 0.75rem);
}
}
</style>実装結果
画面幅を変えると列数が変化します:
カード1
カード2
カード3
カード4
画面の向きで変える
/* 横向き(ランドスケープ) */
@media (orientation: landscape) {
.sidebar {
display: block;
}
}
/* 縦向き(ポートレート) */
@media (orientation: portrait) {
.sidebar {
display: none;
}
}複数条件の組み合わせ
/* タブレット以上 かつ 横向き */
@media (min-width: 768px) and (orientation: landscape) {
.content {
display: grid;
grid-template-columns: 250px 1fr;
}
}
/* 小画面 または 印刷時 */
@media (max-width: 600px), print {
.sidebar {
display: none;
}
}3. Flexboxレイアウト
1次元レイアウト(行または列)に最適です。
基本構造
<div class="flex-container">
<div class="flex-item">アイテム1</div>
<div class="flex-item">アイテム2</div>
<div class="flex-item">アイテム3</div>
</div>
<style>
.flex-container {
display: flex;
/* 方向 */
flex-direction: row; /* 横並び(デフォルト) */
/* flex-direction: column; */ /* 縦並び */
/* 折り返し */
flex-wrap: wrap; /* 折り返す */
/* flex-wrap: nowrap; */ /* 折り返さない */
/* 水平方向の配置 */
justify-content: flex-start; /* 左寄せ */
/* justify-content: center; */ /* 中央 */
/* justify-content: space-between; */ /* 両端揃え */
/* justify-content: space-around; */ /* 均等配置 */
/* 垂直方向の配置 */
align-items: stretch; /* 高さを揃える */
/* align-items: center; */ /* 中央 */
/* align-items: flex-start; */ /* 上揃え */
/* 間隔 */
gap: 1rem;
}
.flex-item {
/* 伸縮 */
flex: 1; /* 均等に伸びる */
/* flex: 0 0 200px; */ /* 固定幅 */
}
</style>実用例:ナビゲーションバー
<nav class="navbar">
<div class="logo">ロゴ</div>
<ul class="nav-links">
<li><a href="#">ホーム</a></li>
<li><a href="#">サービス</a></li>
<li><a href="#">お問い合わせ</a></li>
</ul>
</nav>
<style>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
background: #2a2a2a;
padding: 1rem 2rem;
color: white;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
margin: 0;
padding: 0;
}
/* モバイル: 縦並び */
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 1rem;
}
.nav-links {
flex-direction: column;
gap: 0.5rem;
width: 100%;
}
}
</style>実装結果
🎨 ロゴ
ホームサービスお問い合わせ
中央配置のテクニック
/* 完全中央配置 */
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* 縦方向のみ中央 */
.vertical-center {
display: flex;
align-items: center;
min-height: 100vh;
}
/* 横方向のみ中央 */
.horizontal-center {
display: flex;
justify-content: center;
}4. CSS Gridレイアウト
2次元レイアウト(行と列)に最適です。
基本構造
<div class="grid-container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<style>
.grid-container {
display: grid;
/* 列の定義 */
grid-template-columns: 1fr 1fr 1fr; /* 3列、均等 */
/* grid-template-columns: 200px 1fr 300px; */ /* 固定幅と可変幅 */
/* grid-template-columns: repeat(3, 1fr); */ /* 繰り返し */
/* 行の定義 */
grid-template-rows: auto; /* 自動 */
/* 間隔 */
gap: 1rem; /* 行と列の両方 */
/* row-gap: 1rem; */ /* 行のみ */
/* column-gap: 2rem; */ /* 列のみ */
}
</style>レスポンシブGrid
/* モバイル: 1列 */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
/* タブレット: 2列 */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* デスクトップ: 3列 */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}自動調整Grid(超便利)
/* 最小200px、最大1frで自動的に列数を調整 */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
/* auto-fit: 空白を詰める */
/* auto-fill: 空白を残す */実装結果(画面幅で自動調整)
1
2
3
4
エリア指定レイアウト
<div class="page-layout">
<header>ヘッダー</header>
<nav>ナビ</nav>
<main>メイン</main>
<aside>サイドバー</aside>
<footer>フッター</footer>
</div>
<style>
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 250px;
grid-template-rows: auto 1fr auto;
gap: 1rem;
min-height: 100vh;
}
header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
aside { grid-area: aside; }
footer { grid-area: footer; }
/* モバイル: 1列に */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
</style>実装結果
ヘッダー
メインコンテンツエリア
サイドバー
フッター
5. レスポンシブ画像
srcsetで最適な画像を配信
<img
src="image.jpg"
srcset="
image-small.jpg 480w,
image-medium.jpg 768w,
image-large.jpg 1200w
"
sizes="
(max-width: 480px) 100vw,
(max-width: 768px) 50vw,
33vw
"
alt="説明"
>
解説:
w = 画像の実際の幅(ピクセル)
vw = ビューポート幅の何%で表示するか
ブラウザが自動的に最適な画像を選択pictureタグで完全制御
<picture>
<source media="(min-width: 1024px)" srcset="desktop.jpg">
<source media="(min-width: 768px)" srcset="tablet.jpg">
<img src="mobile.jpg" alt="説明">
</picture>CSSでのレスポンシブ画像
/* 基本 */
img {
max-width: 100%;
height: auto;
}
/* アスペクト比を保つ */
.image-container {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 */
}
.image-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}6. タイポグラフィ
レスポンシブフォントサイズ
/* clamp()で最小・推奨・最大を指定 */
h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
/* 最小 推奨 最大 */
}
/* 従来の方法 */
h1 {
font-size: 1.5rem;
}
@media (min-width: 768px) {
h1 {
font-size: 2rem;
}
}
@media (min-width: 1024px) {
h1 {
font-size: 3rem;
}
}読みやすい行長
/* 最適な行長は45-75文字 */
.text {
max-width: 65ch; /* ch = 文字の幅 */
margin: 0 auto;
}7. モバイルファースト vs デスクトップファースト
モバイルファースト(推奨)
/* モバイル(デフォルト) */
.element {
font-size: 14px;
}
/* タブレット以上 */
@media (min-width: 768px) {
.element {
font-size: 16px;
}
}
/* デスクトップ以上 */
@media (min-width: 1024px) {
.element {
font-size: 18px;
}
}
メリット:
✅ パフォーマンス向上(小さいCSSから)
✅ プログレッシブエンハンスメント
✅ Googleのモバイルファースト評価デスクトップファースト
/* デスクトップ(デフォルト) */
.element {
font-size: 18px;
}
/* タブレット以下 */
@media (max-width: 1023px) {
.element {
font-size: 16px;
}
}
/* モバイル以下 */
@media (max-width: 767px) {
.element {
font-size: 14px;
}
}
使うべき場合:
⚠️ レガシーサイトのリニューアル
⚠️ 主にデスクトップユーザー向け8. タッチデバイス対応
タップ領域のサイズ
/* 最小44x44px(Appleガイドライン) */
.button {
min-width: 44px;
min-height: 44px;
padding: 0.8rem 1.5rem;
}
/* リンクの間隔 */
.nav a {
padding: 1rem;
margin: 0.5rem;
}ホバーとタッチの区別
/* ホバー可能なデバイスのみ */
@media (hover: hover) {
.button:hover {
background: #ffeb3b;
}
}
/* タッチデバイス */
@media (hover: none) {
.button:active {
background: #ffeb3b;
}
}9. パフォーマンス最適化
遅延読み込み
<img src="image.jpg" loading="lazy" alt="説明">
<iframe src="video.html" loading="lazy"></iframe>CSSの最適化
/* 不要な再描画を避ける */
.animated {
will-change: transform;
transform: translateZ(0); /* GPUアクセラレーション */
}
/* アニメーションはtransformを使う */
.move {
transform: translateX(100px); /* ✅ 高速 */
/* left: 100px; */ /* ❌ 遅い */
}10. 実践例:完全なレスポンシブカード
<div class="responsive-cards">
<article class="card">
<img src="image.jpg" alt="説明" loading="lazy">
<div class="card-content">
<h3>タイトル</h3>
<p>説明文がここに入ります。</p>
<a href="#" class="button">詳細を見る</a>
</div>
</article>
</div>
<style>
.responsive-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
padding: 2rem;
}
.card {
background: white;
border: 3px solid #2a2a2a;
box-shadow: 5px 5px 0px rgba(0,0,0,0.1);
overflow: hidden;
transition: transform 0.3s;
}
.card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-content {
padding: 1.5rem;
}
.card h3 {
font-size: clamp(1.2rem, 3vw, 1.5rem);
margin-bottom: 0.5rem;
}
.card p {
margin-bottom: 1rem;
line-height: 1.6;
}
.button {
display: inline-block;
padding: 0.8rem 1.5rem;
background: #ffeb3b;
color: #2a2a2a;
text-decoration: none;
border: 2px solid #2a2a2a;
font-weight: bold;
transition: transform 0.2s;
}
@media (hover: hover) {
.card:hover {
transform: translateY(-5px);
box-shadow: 8px 8px 0px rgba(0,0,0,0.2);
}
.button:hover {
transform: scale(1.05);
}
}
/* モバイル最適化 */
@media (max-width: 480px) {
.responsive-cards {
padding: 1rem;
gap: 1rem;
}
.card-content {
padding: 1rem;
}
}
</style>チェックリスト
必須項目
- ✅ ビューポートメタタグ設定
- ✅ レスポンシブ画像(max-width: 100%)
- ✅ 適切なブレークポイント
- ✅ タッチターゲットサイズ(最小44px)
- ✅ 読みやすいフォントサイズ(最小16px)
推奨項目
- ✅ モバイルファーストアプローチ
- ✅ Flexbox/Gridの活用
- ✅ 画像の遅延読み込み
- ✅ パフォーマンス最適化
- ✅ 実機テスト
デバッグとテスト
Chrome DevTools
F12 → デバイスツールバー(Ctrl+Shift+M)
確認できること:
- 各デバイスサイズでの表示
- ネットワーク速度のシミュレーション
- タッチイベントのエミュレーションテスト用デバイス
必ずテストすべき:
📱 iPhone SE (375x667)
📱 iPhone 12/13/14 (390x844)
📱 iPhone Plus (414x896)
📱 iPad (768x1024)
💻 ノートPC (1366x768)
💻 デスクトップ (1920x1080)まとめ
レスポンシブデザインは必須のスキルです。
基本原則
- モバイルファーストで設計
- コンテンツベースでブレークポイント決定
- Flexbox/Gridを活用
- パフォーマンスを常に意識
- 実機で必ずテスト
学習のステップ
- ビューポートとメディアクエリを理解
- Flexboxで1次元レイアウトをマスター
- Gridで2次元レイアウトをマスター
- 実際のプロジェクトで実践
- パフォーマンス最適化を学ぶ