Day 8: レスポンシブデザイン
今日学ぶこと
- レスポンシブデザインの原則
- メディアクエリ
- モバイルファーストアプローチ
- レスポンシブな画像とコンテンツ
- コンテナクエリ
レスポンシブデザインとは
レスポンシブデザインとは、あらゆる画面サイズに適応するWebデザインのアプローチです。
flowchart LR
subgraph Devices["さまざまなデバイス"]
Mobile["📱 モバイル<br>〜767px"]
Tablet["📱 タブレット<br>768〜1023px"]
Desktop["🖥️ デスクトップ<br>1024px〜"]
end
style Mobile fill:#22c55e,color:#fff
style Tablet fill:#f59e0b,color:#fff
style Desktop fill:#3b82f6,color:#fff
3つの柱
| 要素 | 説明 |
|---|---|
| フルードレイアウト | %やfrで柔軟な幅指定 |
| メディアクエリ | 画面サイズに応じてスタイルを変更 |
| フレキシブルなメディア | 画像・動画の自動リサイズ |
ビューポートメタタグ
レスポンシブデザインの前提条件です。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
必須: このメタタグがないと、モバイルブラウザはデスクトップ版のページを縮小表示してしまいます。
メディアクエリ
基本構文
@media (max-width: 768px) {
.container {
padding: 16px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
}
}
よく使うブレークポイント
/* スマートフォン */
@media (max-width: 767px) { ... }
/* タブレット */
@media (min-width: 768px) and (max-width: 1023px) { ... }
/* デスクトップ */
@media (min-width: 1024px) { ... }
/* 大画面 */
@media (min-width: 1280px) { ... }
| ブレークポイント | デバイス |
|---|---|
| 640px | 小型スマートフォン |
| 768px | タブレット |
| 1024px | ラップトップ |
| 1280px | デスクトップ |
| 1536px | 大画面 |
モバイルファーストアプローチ
小さい画面用のスタイルを先に書き、大きい画面用をmin-widthで追加します。
/* モバイル(デフォルト) */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
/* タブレット以上 */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* デスクトップ以上 */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
}
flowchart LR
Mobile["📱 モバイル<br>1列"] -->|"768px"| Tablet["📱 タブレット<br>2列"]
Tablet -->|"1024px"| Desktop["🖥️ デスクトップ<br>3列"]
style Mobile fill:#22c55e,color:#fff
style Tablet fill:#f59e0b,color:#fff
style Desktop fill:#3b82f6,color:#fff
なぜモバイルファースト?: モバイルユーザーは過半数を占めます。必要最小限のスタイルから始め、大画面で拡張するほうが効率的です。
レスポンシブな画像
img {
max-width: 100%;
height: auto;
}
レスポンシブな動画
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9のアスペクト比 */
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
モダンな方法:
aspect-ratioプロパティを使えば、よりシンプルに書けます。
.video-wrapper {
aspect-ratio: 16 / 9;
width: 100%;
}
.video-wrapper iframe {
width: 100%;
height: 100%;
}
レスポンシブなナビゲーション
/* モバイル: 縦並び */
.nav-links {
display: flex;
flex-direction: column;
gap: 8px;
}
/* デスクトップ: 横並び */
@media (min-width: 768px) {
.nav-links {
flex-direction: row;
gap: 24px;
}
}
レスポンシブなタイポグラフィ
clamp() 関数
h1 {
/* 最小2rem、推奨5vw、最大4rem */
font-size: clamp(2rem, 5vw, 4rem);
}
p {
font-size: clamp(1rem, 2.5vw, 1.25rem);
}
| 引数 | 説明 |
|---|---|
| 最小値 | これ以下にはならない |
| 推奨値 | ビューポートに応じて変化 |
| 最大値 | これ以上にはならない |
推奨:
clamp()を使えば、メディアクエリなしでフォントサイズをスムーズにスケールできます。
コンテナクエリ
画面全体ではなく、親コンテナのサイズに応じてスタイルを変えます。
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
gap: 16px;
}
}
@container (min-width: 600px) {
.card {
font-size: 1.125rem;
}
}
注目: コンテナクエリは比較的新しい機能ですが、すべてのモダンブラウザでサポートされています。
実践: レスポンシブなランディングページ
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--color-primary: #3b82f6;
--max-width: 1200px;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
color: #1e293b;
}
img {
max-width: 100%;
height: auto;
}
/* ヘッダー */
.header {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 16px;
}
/* ヒーロー */
.hero {
text-align: center;
padding: 48px 16px;
}
.hero h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
margin-bottom: 16px;
}
/* カードグリッド */
.cards {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
padding: 32px 16px;
max-width: var(--max-width);
margin: 0 auto;
}
/* フッター */
.footer {
background: #1e293b;
color: #94a3b8;
text-align: center;
padding: 32px 16px;
}
/* タブレット以上 */
@media (min-width: 768px) {
.header {
flex-direction: row;
justify-content: space-between;
padding: 16px 32px;
}
.hero {
padding: 80px 32px;
}
.cards {
grid-template-columns: repeat(2, 1fr);
gap: 24px;
padding: 48px 32px;
}
}
/* デスクトップ以上 */
@media (min-width: 1024px) {
.cards {
grid-template-columns: repeat(3, 1fr);
}
}
まとめ
| 概念 | 説明 |
|---|---|
| レスポンシブデザイン | あらゆる画面サイズに適応 |
| メディアクエリ | @mediaで条件付きスタイル |
| モバイルファースト | 小→大の順でスタイルを追加 |
clamp() |
最小・推奨・最大のフォントサイズ |
| コンテナクエリ | 親要素のサイズに応じた変化 |
max-width: 100% |
画像のレスポンシブ対応 |
重要ポイント
- ビューポートメタタグは必須
- モバイルファーストで
min-widthを使う clamp()でメディアクエリなしのレスポンシブを実現auto-fit+minmax()で柔軟なグリッド
練習問題
問題1: 基本
1列(モバイル)→2列(タブレット)→3列(デスクトップ)のレスポンシブグリッドを作成してください。
問題2: 応用
モバイルでハンバーガーメニュー風(縦並び)、デスクトップで横並びのナビゲーションを作成してください。
チャレンジ問題
メディアクエリを一切使わずに、clamp()、auto-fit、minmax()だけでレスポンシブなページを作成してください。
参考リンク
次回予告: Day 9では「トランジションとアニメーション」について学びます。CSSだけで実現できる動的な表現をマスターしましょう。