技術・開発
CSS Grid完全ガイド - 現代的なレイアウト実装の決定版
「CSSのレイアウトが苦手」「Flexboxだけでは複雑なレイアウトが作れない」——そんな悩みを解決するのがCSS Gridです。2017年に主要ブラウザで対応が完了し、今や現代的なWebサイトには欠かせない技術となっています。
この記事では、MechaToraで15個のツールを作る中で習得したCSS Gridの使い方を、実践的なコード例とともに解説します。基本的な使い方から、レスポンシブ対応、Flexboxとの使い分けまで、実務で使える内容をお伝えします。
CSS Gridとは
2次元レイアウトシステム
CSS Gridは、行(row)と列(column)の両方を同時に制御できる、2次元のレイアウトシステムです:
- Flexbox:1次元(行 OR 列)
- CSS Grid:2次元(行 AND 列)
FlexboxとCSS Gridの使い分け
| 用途 | Flexbox | CSS Grid |
|---|---|---|
| ナビゲーションバー | ✅ | ❌ |
| カード一覧 | △ | ✅ |
| ページ全体のレイアウト | ❌ | ✅ |
| フォーム | △ | ✅ |
| センタリング | ✅ | ✅ |
私の使い分けルール:
- Flexbox:コンポーネント内の1方向の配置
- CSS Grid:ページ全体、カード配置、フォームなどの複雑なレイアウト
CSS Gridの基本
最もシンプルな例
<!-- HTML -->
<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 class="item">5</div>
<div class="item">6</div>
</div>
<!-- CSS -->
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3列、均等幅 */
gap: 1rem; /* 要素間の隙間 */
}
.item {
background: #2563eb;
color: white;
padding: 1rem;
text-align: center;
}
fr単位とは
fr(fraction、分数)は、利用可能なスペースを分割する単位です:
/* 1:1:1 の比率で3列 */
grid-template-columns: 1fr 1fr 1fr;
/* 1:2:1 の比率で3列(中央が2倍の幅) */
grid-template-columns: 1fr 2fr 1fr;
/* 固定幅 + 可変幅 */
grid-template-columns: 200px 1fr 200px;
repeat()関数
同じパターンを繰り返す場合は、repeat()が便利:
/* 3列均等 */
grid-template-columns: repeat(3, 1fr);
/* 4列、交互に200pxと1fr */
grid-template-columns: repeat(2, 200px 1fr);
実践例1:カードグリッド
HTML構造
<div class="card-grid">
<div class="card">
<img src="app1.jpg" alt="地震モニター">
<h3>地震モニター</h3>
<p>リアルタイムで地震情報を通知</p>
</div>
<div class="card">
<img src="app2.jpg" alt="日本酒検索">
<h3>日本酒検索</h3>
<p>3万種類から検索</p>
</div>
<!-- ... 他のカード -->
</div>
CSS実装
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
.card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.2s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.card h3 {
padding: 1rem 1rem 0.5rem;
margin: 0;
}
.card p {
padding: 0 1rem 1rem;
color: #666;
}
auto-fit と minmax() の魔法
auto-fitとminmax()を組み合わせると、レスポンシブ対応が自動化されます:
/* 最小300px、最大1fr */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
/* 意味:
- カードは最低300px幅
- 画面幅に応じて列数が自動調整
- PC: 3〜4列
- タブレット: 2列
- スマホ: 1列
*/
auto-fit vs auto-fill
- auto-fit:空いたスペースを埋める(カードが伸びる)
- auto-fill:空いたスペースはそのまま(カードは伸びない)
実践例2:ページ全体のレイアウト
Holy Grail Layout
ヘッダー、サイドバー、メイン、フッターを持つ典型的なレイアウト:
<!-- HTML -->
<div class="page-layout">
<header>ヘッダー</header>
<aside>サイドバー</aside>
<main>メインコンテンツ</main>
<footer>フッター</footer>
</div>
<!-- CSS -->
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
header {
grid-area: header;
background: #1e40af;
color: white;
padding: 1rem;
}
aside {
grid-area: sidebar;
background: #f3f4f6;
padding: 1rem;
}
main {
grid-area: main;
padding: 1rem;
}
footer {
grid-area: footer;
background: #374151;
color: white;
padding: 1rem;
text-align: center;
}
/* レスポンシブ対応 */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
grid-template-areas の利点
- 視覚的に分かりやすい:レイアウトがASCIIアートで見える
- 名前で管理:数値ではなく名前で配置
- レスポンシブが簡単:areas を書き換えるだけ
実践例3:フォームレイアウト
<!-- HTML -->
<form class="form-grid">
<label for="name">名前</label>
<input type="text" id="name" />
<label for="email">メールアドレス</label>
<input type="email" id="email" />
<label for="message">メッセージ</label>
<textarea id="message" rows="5"></textarea>
<div></div> <!-- 空のdiv(ラベル列を埋めるため) -->
<button type="submit">送信</button>
</form>
<!-- CSS -->
.form-grid {
display: grid;
grid-template-columns: 150px 1fr;
gap: 1rem;
max-width: 600px;
margin: 2rem auto;
}
.form-grid label {
align-self: center;
font-weight: bold;
}
.form-grid input,
.form-grid textarea {
padding: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 4px;
}
.form-grid button {
background: #2563eb;
color: white;
padding: 0.75rem 2rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
/* スマホではラベルを上に配置 */
@media (max-width: 640px) {
.form-grid {
grid-template-columns: 1fr;
}
}
実践例4:ダッシュボード
<!-- HTML -->
<div class="dashboard">
<div class="widget large">大きいウィジェット</div>
<div class="widget">ウィジェット1</div>
<div class="widget">ウィジェット2</div>
<div class="widget">ウィジェット3</div>
<div class="widget tall">縦長ウィジェット</div>
<div class="widget">ウィジェット4</div>
</div>
<!-- CSS -->
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-auto-rows: 200px; /* 各行の高さ */
gap: 1.5rem;
padding: 1.5rem;
}
.widget {
background: white;
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
/* 大きいウィジェット:2列×2行 */
.widget.large {
grid-column: span 2;
grid-row: span 2;
}
/* 縦長ウィジェット:2行 */
.widget.tall {
grid-row: span 2;
}
grid-column と grid-row
特定の要素だけサイズを変える:
/* 2列分のスペースを占有 */
grid-column: span 2;
/* 2行分のスペースを占有 */
grid-row: span 2;
/* より明示的な書き方 */
grid-column: 1 / 3; /* 1列目から3列目の手前まで */
grid-row: 2 / 4; /* 2行目から4行目の手前まで */
よく使うCSSプロパティ一覧
コンテナ(親要素)
| プロパティ | 説明 | 例 |
|---|---|---|
display |
Grid有効化 | grid |
grid-template-columns |
列の定義 | 1fr 2fr 1fr |
grid-template-rows |
行の定義 | auto 1fr auto |
gap |
要素間の隙間 | 1rem |
grid-template-areas |
エリア名で配置 | "header header" |
アイテム(子要素)
| プロパティ | 説明 | 例 |
|---|---|---|
grid-column |
列の占有範囲 | span 2 |
grid-row |
行の占有範囲 | 1 / 3 |
grid-area |
エリア名を指定 | header |
justify-self |
自身の水平位置 | center |
align-self |
自身の垂直位置 | start |
MechaToraでの実際の使用例
トップページのアプリ一覧
.app-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 2rem;
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
}
@media (max-width: 640px) {
.app-grid {
grid-template-columns: 1fr;
padding: 1rem;
gap: 1rem;
}
}
ブログ記事一覧
.article-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 2.5rem;
}
.article-card {
display: grid;
grid-template-rows: 200px auto 1fr auto;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
まとめ
CSS Gridを使うべき場面
- ✅ カード配置(3列、4列など)
- ✅ ページ全体のレイアウト(ヘッダー、サイドバー、メイン、フッター)
- ✅ ダッシュボード
- ✅ フォーム
- ✅ ギャラリー
Flexboxを使うべき場面
- ✅ ナビゲーションバー
- ✅ ボタングループ
- ✅ カード内の要素配置
- ✅ 単純な1方向配置
最初に覚えるべき3つのパターン
- 均等3列グリッド:
grid-template-columns: repeat(3, 1fr) - レスポンシブカード:
repeat(auto-fit, minmax(300px, 1fr)) - ページレイアウト:
grid-template-areas
CSS Gridは最初は難しく感じるかもしれませんが、基本パターンを覚えてしまえば、あらゆるレイアウトが簡単に実現できます。MechaToraでは、全15個のツールでCSS Gridを活用し、レスポンシブ対応を効率化しています。
ぜひ、実際に手を動かして試してみてください!