CSSのレイアウト手法は、長い歴史の中で何度も革命を経てきました。
float で苦労していた時代。display: inline-block と格闘した時代。そして Flexbox の登場で、ようやく縦横の配置が楽になった——と思いきや、CSS Grid という新たな武器が加わりました。
Grid は「レイアウトのための仕様」として設計された、初めての CSS プロパティです。Flexbox が「1次元(横または縦)」のレイアウトに強いのに対し、Grid は**「2次元(横と縦の両方)」を同時に**扱えます。
この記事では、CSS Grid の基本から実践的なパターンまで、体系的に解説します。
Grid と Flexbox——どう使い分けるか
まず、よくある誤解を解いておきましょう。
Grid は Flexbox の上位互換ではありません。それぞれに得意領域があり、使い分けるのが正解です。
Grid が得意なこと
- 2次元レイアウト: 行と列を同時にコントロール
- ページ全体のレイアウト: ヘッダー、サイドバー、メイン、フッター
- 位置の明示: 「この要素は2列目の3行目に配置」
- 重ね合わせ: 要素を同じセルに配置
Flexbox が得意なこと
- 1次元の配置: 横並び、縦並び
- コンポーネント内部: ナビゲーションバー、カード内のレイアウト
- 動的な幅: 中身に応じて柔軟に伸縮
- 順序の変更:
orderプロパティで簡単に並べ替え
実務での使い分け
| 用途 | 推奨 |
|---|---|
| ページ全体の骨格 | Grid |
| ダッシュボードのウィジェット配置 | Grid |
| ナビゲーションバー | Flexbox |
| カード内のレイアウト | Flexbox |
| カードの一覧(グリッド表示) | Grid |
| フォームのラベル+入力欄 | Flexbox |
結論: ページレベルは Grid、コンポーネントレベルは Flexbox——という使い分けが多いです。もちろん例外はありますし、組み合わせて使うことも多い。
Grid の基本構造
Grid レイアウトは、親要素(コンテナ)と子要素(アイテム) の関係で成り立ちます。
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
Grid コンテナを有効化
.container {
display: grid;
}
この一行で、子要素が Grid アイテムになります。ただし、これだけでは見た目は変わりません。列(columns)と行(rows)を定義する必要があります。
列と行を定義
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 100px auto 50px;
}
この例は:
- 列: 200px、残り全部(1fr)、200px の3列
- 行: 100px、中身に応じて(auto)、50px の3行
合計 3 × 3 = 9 個のセルができます。
fr 単位——柔軟なサイズ指定
Grid で最も重要な単位が fr(fraction) です。
fr は「残りのスペースを分配する」単位。パーセンテージに似ていますが、余白やギャップを考慮した計算を自動で行ってくれます。
基本的な使い方
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
}
この例では、3列が 1:2:1 の比率で分配されます。中央の列は左右の2倍の幅。
px と fr の組み合わせ
.container {
display: grid;
grid-template-columns: 250px 1fr;
}
左列は固定 250px、右列は残り全部。サイドバー + メインコンテンツのレイアウトに最適。
なぜ fr を使うのか
パーセンテージ(%)でも似たことはできますが、fr には利点があります。
- 計算が楽: 100% からギャップを引いて…といった計算が不要
- 意図が明確: 「残りを分配する」という意図がコードから読み取れる
- 柔軟性: px や auto と自然に組み合わせられる
gap——要素間の余白
Grid アイテム間の余白は、gap プロパティで設定します。
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
行と列で別の値
.container {
gap: 20px 10px; /* 行間 列間 */
/* または */
row-gap: 20px;
column-gap: 10px;
}
margin との違い
以前は、要素間の余白を margin で設定していました。しかし margin には問題があります。
- 最初と最後の要素にも余白がつく(外側にはみ出す)
- 上下の margin は相殺(collapse)される
gap なら、要素間にだけ余白がつきます。シンプルで予測可能。
repeat()——繰り返しの簡略化
同じパターンを繰り返すとき、repeat() を使います。
/* 冗長な書き方 */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* repeat() を使う */
grid-template-columns: repeat(4, 1fr);
パターンの繰り返し
grid-template-columns: repeat(3, 100px 200px);
/* → 100px 200px 100px 200px 100px 200px */
交互に幅が変わるレイアウトも簡単に。
アイテムの配置——グリッドラインを使う
Grid の真価は、アイテムを任意の位置に配置できることです。
グリッドラインとは
Grid を定義すると、自動的にライン(線)に番号が振られます。
1 2 3 4
| | | |
├─────┼─────┼─────┤ 1
│ │ │ │
├─────┼─────┼─────┤ 2
│ │ │ │
├─────┼─────┼─────┤ 3
3列のグリッドには、4本の縦ライン(1〜4)があります。
アイテムの配置
.item {
grid-column: 2; /* 2番目の列ラインから開始 */
grid-row: 1; /* 1番目の行ラインから開始 */
}
複数セルにまたがる
.item {
grid-column: 1 / 3; /* 1番から3番まで(2列分) */
grid-row: 1 / 4; /* 1番から4番まで(3行分) */
}
スラッシュ(/)で開始ラインと終了ラインを指定。
span を使う書き方
「何列分」「何行分」という指定もできます。
.item {
grid-column: span 2; /* 2列分 */
grid-row: span 3; /* 3行分 */
}
開始位置は自動、サイズだけ指定。
grid-template-areas——名前で配置
ライン番号は正確ですが、直感的ではありません。名前で配置する方法もあります。
エリアに名前をつける
.container {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
ASCII アートのように、視覚的にレイアウトを定義できます。
空のセルを作る
ピリオド(.)を使います。
grid-template-areas:
"header header header"
"sidebar main ."
"footer footer footer";
右上のセルは空になります。
利点と欠点
利点:
- レイアウトが視覚的にわかる
- HTMLの順序に依存しない
欠点:
- エリア名の管理が必要
- 複雑なレイアウトには向かない
シンプルなページレイアウトには非常に有効ですが、ダッシュボードのように動的に変わるレイアウトには向きません。
レスポンシブ対応——auto-fill と auto-fit
Grid の真骨頂は、メディアクエリなしでレスポンシブ対応できること。
auto-fill と minmax()
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
この魔法のような一行で:
- 各アイテムは最小 250px、最大 1fr
- 画面幅に応じて列数が自動調整
- 余白も自動で均等配分
auto-fill vs auto-fit
| 値 | 挙動 |
|---|---|
auto-fill | 空のトラック(列)も作成 |
auto-fit | 空のトラックを潰してアイテムを広げる |
アイテム数が少ないとき、違いが出ます。
auto-fill: アイテムは固定幅のまま、右側に空きができるauto-fit: アイテムが広がって、空きを埋める
多くの場合、auto-fit の方が直感的な挙動になります。
メディアクエリとの併用
もちろん、メディアクエリとの併用も可能です。
.container {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
@media (min-width: 768px) {
.container {
grid-template-columns: 200px 1fr;
}
}
モバイルでは1列、タブレット以上ではサイドバー + メイン。
実践的なレイアウトパターン
ここまでの知識を使って、よくあるレイアウトを実装してみましょう。
カードグリッド
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
商品一覧、ブログ記事一覧など。カードが画面幅に応じて自動で並び替わります。
聖杯レイアウト(Holy Grail)
ヘッダー、フッター、左右サイドバー、メインコンテンツ——Webデザインの定番です。
.holy-grail {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"left main right"
"footer footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.left { grid-area: left; }
.main { grid-area: main; }
.right { grid-area: right; }
.footer { grid-area: footer; }
min-height: 100vh で、コンテンツが少なくても画面いっぱいに。
ダッシュボード
ウィジェットが並ぶダッシュボードは、Grid の本領発揮です。
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto 1fr 1fr;
gap: 16px;
}
.widget-large {
grid-column: span 2;
grid-row: span 2;
}
.widget-wide {
grid-column: span 2;
}
特定のウィジェットを大きく表示。span で柔軟にサイズ調整。
配置の調整——justify と align
Grid アイテムは、セル内でさらに細かく配置を調整できます。
コンテナ全体の配置
.container {
justify-items: center; /* 水平方向(各アイテム) */
align-items: center; /* 垂直方向(各アイテム) */
}
ショートハンド
.container {
place-items: center; /* 両方向中央 */
}
個別のアイテムを調整
.item {
justify-self: end; /* このアイテムだけ右寄せ */
align-self: start; /* このアイテムだけ上寄せ */
}
グリッド全体の位置
コンテナにスペースが余っている場合、グリッド全体の位置も調整できます。
.container {
justify-content: center; /* グリッド全体を中央に */
align-content: start; /* グリッド全体を上に */
}
よくあるつまずきポイント
Grid を使い始めると、いくつかのハマりポイントがあります。
1. はみ出し問題
/* 問題: 固定幅がコンテナをはみ出す */
grid-template-columns: 300px 300px 300px;
/* 解決: minmax で最大幅を制限 */
grid-template-columns: repeat(3, minmax(0, 300px));
2. 画像がセルからはみ出す
/* 画像に max-width を設定 */
.grid-item img {
max-width: 100%;
height: auto;
}
3. 高さが揃わない
デフォルトでは align-items: stretch なので高さは揃うはず。揃わない場合は、アイテムに height が設定されていないか確認。
4. IE は非対応
Internet Explorer は Grid の部分的なサポートのみ。2025年現在、IE対応は不要な場合がほとんど。気にする必要はありません。
Grid と Flexbox の組み合わせ
実際のプロジェクトでは、Grid と Flexbox を組み合わせて使います。
/* ページ全体は Grid */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
}
/* ナビゲーションは Flexbox */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
/* カードグリッドは Grid */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
/* カード内部は Flexbox */
.card {
display: flex;
flex-direction: column;
}
適材適所。それぞれの得意領域を活かすのが、モダンなCSSの書き方です。
まとめ——レイアウトの新時代
CSS Grid は、Webレイアウトの歴史における革命です。
float や position: absolute で苦労していた時代は終わりました。Grid と Flexbox を使いこなせば、どんな複雑なレイアウトも数行で実現できます。
ポイント:
- ✅
display: gridで有効化 - ✅
grid-template-columns/rowsで構造定義 - ✅
fr単位で柔軟なサイズ指定 - ✅
gapで余白設定 - ✅
repeat(auto-fit, minmax())でレスポンシブ対応 - ✅
grid-template-areasで視覚的に配置 - ✅ Flexbox と組み合わせて使う
Grid を習得すれば、レイアウトで悩む時間が激減します。その時間を、デザインやユーザー体験の向上に充てましょう。
まずは簡単なカードグリッドから試してみてください。repeat(auto-fit, minmax(280px, 1fr)) の魔法を体験すれば、Grid の虜になるはずです。
関連情報
- MDN CSS Grid レイアウト(リファレンス・詳細仕様)
- Figma入門ガイド(UIデザインの基礎)
- Webフォントの基礎(タイポグラフィと組み合わせ)
- 配色の基礎理論(レイアウトと色彩の関係)