CSS Flexbox vs Grid: どちらのレイアウトシステムを使うべきか?
FlexboxとCSS Gridはどちらも似たような結果を生み出すことができるため、開発者は半分の確率で間違った方を選択してしまいます。違いは1次元か2次元かという点に集約されます。自分がどちらを扱っているのかを把握すれば、選択は明らかになります。
一言で言うなら
1つの方向(行または列)にアイテムを並べる場合は Flexbox を使用します。同時に2つの方向(行と列の両方)のレイアウトを制御する必要がある場合は CSS Grid を使用します。
決定的な違いはこれだけです。それ以外はすべて、なぜそのルールが実用的なのかを詳しく説明したものです。
Flexboxが本当に得意なこと
Flexboxは単一の軸に沿ってスペースを分配するために設計されました。その優れた機能は、各アイテムの正確な寸法を指定しなくても、アイテムが自然に成長、縮小、折り返されることです。
Flexboxが正しい選択となるのは、次のようなケースです:
- ナビゲーションバー — 特定のアイテムを右側に押し出したり(
margin-left: auto)、均等に配置したりするリンクの行(justify-content: space-between) - カードの行 — コンテンツの長さに関わらず、各カードが同じ高さになる場合(
align-items: stretchで自動的に処理されます) - 要素のセンタリング — コンテナ内での水平・垂直方向への中央配置。CSS 3行:
display: flex; justify-content: center; align-items: center - ボタングループ、アイコン + ラベルの組み合わせ、および子要素を一定の間隔を持って横に並べる必要があるすべてのコンポーネント
- 折り返されるリスト — スペースがなくなったときにアイテムを次の行に折り返す場合(<
flex-wrap: wrap)
.navbar {
display: flex;
align-items: center;
gap: 1rem;
}
.navbar .logo { margin-right: auto; }
/* ロゴは左、リンクは右に配置される */
CSS Gridが本当に得意なこと
Gridは二次元レイアウトのために設計されました。行と列の両方を定義し、アイテムをセル内に正確に配置したり、複数の行や列にまたがらせたり、両方の方向に隙間を作成したりすることができます。
Gridが正しい選択となるのは、次のようなケースです:
- ページレイアウト — ヘッダー、サイドバー、メインコンテンツ、フッターを互いに関連付けて配置する
- 雑誌やダッシュボードのレイアウト — 異なるアイテムが異なる量のスペースを占有する場合
- 画像ギャラリー — 画像のサイズに関わらず、一貫したグリッド構造を持つ場合
- フォームレイアウト — ラベルと入力フィールドの両方を水平および垂直方向に整列させる必要がある場合
- 行と列の両方を同時に意識するすべてのレイアウト
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100dvh;
}
比較例:カードグリッド
ここで混乱が生じます。両方のシステムでカードの行を作成できます:
.card-row {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.card { flex: 1 1 280px; }
Grid の場合:
.card-row {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
}
どちらも動作します。ここでは通常、Grid 版が推奨されます。なぜなら、<minmax> を伴う <auto-fill> はより予測可能な列の挙動を提供し、各列が正確に同じ幅になり、グリッドがきれいに再配置されるからです。Flexbox 版は、カードの幅が可変で、利用可能なスペースをより流動的に使用したい場合に適しています。
整列の仕組みの違い
Flexboxでは、アイテムをメイン軸(選択した方向)とクロス軸(それに対して垂直な方向)に沿って整列させます。見えないグリッド内のセルにおける位置を独立して制御することはできません。
Gridでは、すべてのアイテムが行と列の両方の位置を持つセル内に存在します。アイテムを「2行目、3列目」に明示的に配置することも、ブラウザに自動配置させることも可能です。Flexboxにはセルの概念がなく、アイテムは指定した方向に流れるだけです。
よくある間違い
単純な中央揃えに Grid を使う: <display: flex; align-items: center; justify-content: center> は、単一の要素のためにグリッドを設定するよりも高速です。単一軸のタスクでは Flexbox が勝ります。
フルページレイアウトに Flexbox を使う: 位置関係を関連付ける必要があるコンポーネントが2つ以上(ヘッダー + サイドバー + コンテンツ + フッター)になった時点で、Flexbox には第2軸がないことが問題になります。Grid は名前付きエリアでこれを処理します。
Flexbox の列を Grid の行の代用として使う: <flex-direction: column> はアイテムを垂直に積み重ねますが、複数の列にわたるコンテンツを同時に整列させる能力が失われます。列のことを考えているなら、Grid に切り替えてください。
両方を組み合わせて使う
Grid と Flexbox は排他的な関係ではありません。最も一般的な実用的なパターンは、ページレベルのレイアウトに Grid、各セクション内に Flexbox を使うことです:
- Grid がサイドバー、ヘッダー、メインコンテンツエリアの配置を決定する
- ナビゲーション内(ヘッダー領域)では、Flexbox がロゴ + リンク + CTA ボタンの行を処理する
- メインコンテンツエリア内では、カードグリッドが列構造のために Grid を使用する
- 各カード内では、Flexbox がアイコン + テキスト + ボタンのレイアウトを処理する
この構成パターン — 構造には Grid、コンポーネントには Flexbox — は、ほとんどのモダンな CSS フレームワーク(Tailwind, Bootstrap)が内部で動作している仕組みです。
プロパティのクイックリファレンス
| やりたいこと | Flexbox | Grid |
|---|---|---|
| レイアウト方向の設定 | flex-direction | grid-template-columns/rows |
| アイテム間のスペース | gap または <justify-content> | <gap> |
| クロス軸での整列 | align-items | align-items |
| 特定のアイテムを配置する | 直接は不可能 | <grid-column / <grid-row> |
| アイテムの高さを揃える | align-items: stretch> | デフォルトの動作 |
| メディアクエリなしのレスポンシブ | <flex-wrap: wrap + <flex-basis> | <auto-fill + <minmax()> |
Flexboxレイアウトを視覚的に構築
私たちのビジュアルCSS Flexbox Generatorを使用して、flexコンテナの作成、配置の調整を行い、生成されたCSSを数秒でコピーしましょう。