CSS Grid と Flexbox の違い
CSSのレイアウトシステムにはGridとFlexboxの2つがあります。結論から言うと:
- Flexbox: 1方向(横 or 縦)のレイアウトに最適
- Grid: 2方向(横と縦)のレイアウトに最適
比較表
| 項目 | Flexbox | Grid |
|---|---|---|
| 方向 | 1次元(行 or 列) | 2次元(行と列) |
| コンテンツ起点 | コンテンツサイズに合わせる | グリッド構造に合わせる |
| 代表的な用途 | ナビゲーション、カード横並び | ページレイアウト、ダッシュボード |
| ブラウザ対応 | ほぼ100% | ほぼ100% |
| 学習コスト | やや低い | やや高い |
Flexbox の基本
横並び
.container {
display: flex;
gap: 16px;
}
<div class="container">
<div>アイテム1</div>
<div>アイテム2</div>
<div>アイテム3</div>
</div>
主要プロパティ
.container {
display: flex;
/* 主軸の方向 */
flex-direction: row; /* 横並び(デフォルト) */
flex-direction: column; /* 縦並び */
/* 主軸の配置 */
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; /* 上揃え */
/* 折り返し */
flex-wrap: nowrap; /* 折り返さない(デフォルト) */
flex-wrap: wrap; /* 折り返す */
/* 間隔 */
gap: 16px;
}
子要素のプロパティ
.item {
/* 伸びる比率 */
flex-grow: 1;
/* 縮む比率 */
flex-shrink: 0;
/* 基準サイズ */
flex-basis: 200px;
/* ショートハンド */
flex: 1 0 200px; /* grow shrink basis */
flex: 1; /* flex: 1 1 0% と同じ */
}
Grid の基本
グリッドレイアウト
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3等分 */
gap: 16px;
}
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
主要プロパティ
.container {
display: grid;
/* 列の定義 */
grid-template-columns: 200px 1fr 200px; /* 固定+可変+固定 */
grid-template-columns: repeat(3, 1fr); /* 3等分 */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* レスポンシブ */
/* 行の定義 */
grid-template-rows: 60px 1fr 40px; /* ヘッダー+メイン+フッター */
grid-auto-rows: minmax(100px, auto); /* 自動行の最小高さ */
/* 間隔 */
gap: 16px;
column-gap: 24px;
row-gap: 16px;
}
エリア名で配置
.container {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
子要素の配置
.item {
/* 列の位置 */
grid-column: 1 / 3; /* 1列目から3列目まで(2列分) */
grid-column: span 2; /* 2列分 */
/* 行の位置 */
grid-row: 1 / 3; /* 1行目から3行目まで */
}
実践パターン: Flexbox が最適なケース
ナビゲーションバー
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 60px;
}
.nav-links {
display: flex;
gap: 24px;
list-style: none;
}
カードの横並び(中央揃え)
.card {
display: flex;
align-items: center;
gap: 16px;
padding: 16px;
}
.card-icon {
flex-shrink: 0;
width: 48px;
height: 48px;
}
.card-content {
flex: 1;
min-width: 0; /* テキスト省略のために必要 */
}
ボタングループ
.button-group {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.button-group--right {
justify-content: flex-end;
}
.button-group--center {
justify-content: center;
}
完全中央揃え
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
実践パターン: Grid が最適なケース
ダッシュボード
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(150px, auto);
gap: 16px;
}
.widget-large {
grid-column: span 2;
grid-row: span 2;
}
.widget-wide {
grid-column: span 2;
}
レスポンシブカードグリッド
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
auto-fill と minmax の組み合わせで、メディアクエリなしでレスポンシブなグリッドが作れます。
フォームレイアウト
.form {
display: grid;
grid-template-columns: 120px 1fr;
gap: 16px;
align-items: center;
}
.form-full {
grid-column: 1 / -1; /* 全幅 */
}
<form class="form">
<label>名前</label>
<input type="text" />
<label>メール</label>
<input type="email" />
<div class="form-full">
<button type="submit">送信</button>
</div>
</form>
Grid と Flexbox の併用
実際のプロジェクトでは両方を組み合わせて使います。
/* ページ全体のレイアウト → Grid */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
min-height: 100vh;
}
/* ヘッダー内のレイアウト → Flexbox */
.header {
grid-column: 1 / -1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
/* サイドバーのメニュー → Flexbox */
.sidebar-menu {
display: flex;
flex-direction: column;
gap: 4px;
}
/* メインコンテンツのカードグリッド → Grid */
.content {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
padding: 24px;
}
/* カード内のレイアウト → Flexbox */
.card {
display: flex;
flex-direction: column;
gap: 12px;
}
レスポンシブデザインのコツ
Flexbox のレスポンシブ
.container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.item {
flex: 1 1 300px; /* 最小300px、残りは均等分配 */
}
Grid のレスポンシブ
/* メディアクエリなしでレスポンシブ */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 16px;
}
/* メディアクエリで切り替え */
.layout {
display: grid;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.layout {
grid-template-columns: 250px 1fr;
}
}
auto-fill vs auto-fit の違い
/* auto-fill: 空のトラックが残る */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit: 空のトラックが潰れて残りのアイテムが伸びる */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
アイテム数が少ない場合に違いが出ます。多くの場合 auto-fill が安全です。
選択フローチャート
- 1方向のレイアウト? → Flexbox
- 2方向のレイアウト? → Grid
- コンテンツサイズに合わせたい? → Flexbox
- 固定のグリッド構造に合わせたい? → Grid
- どちらでもいけそう? → 好みでOK(併用も可)
まとめ
| パターン | 推奨 |
|---|---|
| ナビバー、ボタン並び | Flexbox |
| カードグリッド | Grid |
| ページ全体のレイアウト | Grid |
| カード内の縦並び | Flexbox |
| フォームのラベル+入力 | Grid |
| 中央揃え | Flexbox or Grid |
Flexbox と Grid はどちらか一方ではなく、組み合わせて使うのが現代のCSS開発です。迷ったらまず Flexbox で試し、2次元の配置が必要になったら Grid に切り替えましょう。
CSSのpx・rem・em変換には、Assistyのpx変換ツールが便利です。ブラウザ上で単位変換を素早く計算できます。