Day 7: CSS Grid
今日学ぶこと
- CSS Gridの基本概念
- グリッドコンテナのプロパティ
- グリッドアイテムの配置
- テンプレートエリア
- FlexboxとGridの使い分け
CSS Gridとは
CSS Gridは、2次元のレイアウトを作るための仕組みです。行(row)と列(column)を同時に制御できます。
flowchart LR
subgraph Compare["Flexbox vs Grid"]
Flex["Flexbox<br>1次元<br>横並び or 縦並び"]
Grid["Grid<br>2次元<br>行 × 列"]
end
style Flex fill:#3b82f6,color:#fff
style Grid fill:#22c55e,color:#fff
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}
グリッドの基本
grid-template-columns / grid-template-rows
/* 3等分 */
.grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
/* repeat関数 */
.grid-3 {
grid-template-columns: repeat(3, 1fr);
}
/* 固定 + 可変 */
.sidebar-layout {
grid-template-columns: 250px 1fr;
}
/* 行の指定 */
.grid {
grid-template-rows: 80px 1fr 60px;
}
fr 単位
fr(fraction)は、残りスペースを分配する単位です。
/* 1:2:1 の比率で分配 */
grid-template-columns: 1fr 2fr 1fr;
/* 200px固定 + 残りを均等分配 */
grid-template-columns: 200px 1fr 1fr;
| 値 | 説明 |
|---|---|
1fr |
残りスペースの1割当 |
200px |
固定200px |
auto |
コンテンツに合わせる |
minmax(200px, 1fr) |
最小200px〜最大1fr |
gap(間隔)
.grid {
gap: 16px; /* 行と列の両方 */
gap: 16px 24px; /* 行間 列間 */
row-gap: 16px;
column-gap: 24px;
}
アイテムの配置
行と列の番号で配置
.item {
grid-column: 1 / 3; /* 1列目から3列目まで(2列分) */
grid-row: 1 / 2; /* 1行目から2行目まで(1行分) */
}
/* span を使う */
.item-wide {
grid-column: span 2; /* 2列分 */
}
.item-tall {
grid-row: span 3; /* 3行分 */
}
flowchart TB
subgraph GridLines["グリッド線の番号"]
L["列: 1 | 2 | 3 | 4<br>行: 1<br>──────<br>行: 2<br>──────<br>行: 3"]
end
style L fill:#3b82f6,color:#fff
grid-template-areas
名前を付けてレイアウトを視覚的に定義できます。
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
grid-template-columns: 250px 1fr 1fr;
grid-template-rows: 80px 1fr 60px;
min-height: 100vh;
gap: 0;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }
ポイント:
grid-template-areasを使うと、レイアウトをASCIIアートのように視覚的に定義できます。
自動配置
auto-fill と auto-fit
/* auto-fill: カラム数を自動調整(空スペース保持) */
.grid-auto {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
/* auto-fit: カラム数を自動調整(空スペースを埋める) */
.grid-auto-fit {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
| 値 | 説明 |
|---|---|
auto-fill |
可能な限り列を作る(空セルあり) |
auto-fit |
可能な限り列を作り、アイテムを引き伸ばす |
推奨: レスポンシブなカードグリッドには
repeat(auto-fit, minmax(250px, 1fr))がよく使われます。メディアクエリなしでレスポンシブなグリッドを実現できます。
配置プロパティ
コンテナ全体
.grid {
justify-items: center; /* セル内の水平方向 */
align-items: center; /* セル内の垂直方向 */
place-items: center; /* 上記2つのショートハンド */
justify-content: center; /* グリッド全体の水平方向 */
align-content: center; /* グリッド全体の垂直方向 */
place-content: center; /* 上記2つのショートハンド */
}
個別のアイテム
.item {
justify-self: end; /* このアイテムの水平方向 */
align-self: center; /* このアイテムの垂直方向 */
place-self: center end;
}
Flexbox と Grid の使い分け
| 状況 | 推奨 |
|---|---|
| 横一列のナビゲーション | Flexbox |
| カードの横並び | Flexbox or Grid |
| ページ全体のレイアウト | Grid |
| 2次元のグリッドレイアウト | Grid |
| 要素の中央寄せ | どちらでもOK |
| コンテンツサイズで幅が決まる | Flexbox |
| 列数や幅を明示的に制御 | Grid |
flowchart TB
Q1{"2次元の<br>レイアウト?"}
Q2{"コンテンツサイズ<br>で決まる?"}
Grid["CSS Grid"]
Flex["Flexbox"]
Q1 -->|"はい"| Grid
Q1 -->|"いいえ"| Q2
Q2 -->|"はい"| Flex
Q2 -->|"いいえ"| Grid
style Grid fill:#22c55e,color:#fff
style Flex fill:#3b82f6,color:#fff
実践: ダッシュボードレイアウト
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
color: #1e293b;
}
/* ページ全体のレイアウト */
.dashboard {
display: grid;
grid-template-areas:
"sidebar header"
"sidebar main";
grid-template-columns: 250px 1fr;
grid-template-rows: 64px 1fr;
min-height: 100vh;
}
.header {
grid-area: header;
background: white;
border-bottom: 1px solid #e2e8f0;
display: flex;
align-items: center;
padding: 0 24px;
}
.sidebar {
grid-area: sidebar;
background: #1e293b;
color: white;
padding: 24px;
}
.main {
grid-area: main;
background: #f8fafc;
padding: 24px;
}
/* カードグリッド */
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
margin-bottom: 24px;
}
.stat-card {
background: white;
padding: 24px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.stat-card h3 {
font-size: 0.875rem;
color: #64748b;
margin-bottom: 8px;
}
.stat-card .number {
font-size: 2rem;
font-weight: 700;
}
/* メインコンテンツのグリッド */
.content-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
}
.panel {
background: white;
padding: 24px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
まとめ
| プロパティ | 対象 | 説明 |
|---|---|---|
display: grid |
コンテナ | Grid有効化 |
grid-template-columns |
コンテナ | 列の定義 |
grid-template-rows |
コンテナ | 行の定義 |
grid-template-areas |
コンテナ | 名前で領域定義 |
gap |
コンテナ | セル間の間隔 |
grid-column / grid-row |
アイテム | 配置位置 |
grid-area |
アイテム | 名前付き領域に配置 |
fr |
値 | 残りスペースの分配 |
重要ポイント
fr単位で柔軟なスペース分配- **
grid-template-areas**で視覚的にレイアウトを定義 - **
auto-fit+minmax()**でレスポンシブグリッド - Flexboxとの使い分けを意識する
練習問題
問題1: 基本
3列のカードグリッドをCSS Gridで作成してください。
問題2: 応用
grid-template-areasを使って、ヘッダー・サイドバー・メイン・フッターの4領域レイアウトを作成してください。
チャレンジ問題
auto-fitとminmax()を使って、メディアクエリなしで画面幅に応じてカラム数が変化するレスポンシブグリッドを作成してください。
参考リンク
- MDN - CSS Grid Layout
- CSS-Tricks - A Complete Guide to CSS Grid
- Grid Garden — ゲームで学ぶCSS Grid
次回予告: Day 8では「レスポンシブデザイン」について学びます。メディアクエリとモバイルファーストのアプローチをマスターしましょう。