はじめに
モダンCSSでレイアウトを構築する際、FlexboxとCSS Gridという2つの強力なツールを選択できます。しかし、「どちらを使えばよいのか」「併用しても問題ないのか」という疑問を持つ方は少なくありません。
結論から言えば、FlexboxとCSS Gridは競合するものではなく、それぞれ異なる得意分野を持つ相互補完的なレイアウト手法です。適切な場面で適切なツールを選択することで、保守性の高いCSSを効率的に記述できます。
本記事では、FlexboxとCSS Gridの使い分けについて以下の内容を解説します。
- FlexboxとCSS Gridの根本的な違い(1次元 vs 2次元)
- それぞれが得意なレイアウトパターン
- 選択の判断基準となる5つのチェックポイント
- FlexboxとGridを組み合わせる実践パターン
- よくある設計ミスと改善方法
前提条件
本記事を読み進めるにあたり、以下の知識があることを前提としています。
- Flexboxの基本概念(フレックスコンテナ・フレックスアイテム・主軸・交差軸)
- CSS Gridの基本概念(グリッドコンテナ・グリッドアイテム・トラック・ライン)
justify-content、align-itemsなどの配置プロパティ
これらの基礎知識については、以下の記事で解説しています。
動作確認環境
- Google Chrome 131以降
- Firefox 133以降
- Safari 18以降
- Microsoft Edge 131以降
FlexboxとCSS Gridの根本的な違い
FlexboxとCSS Gridの最も重要な違いは「次元」です。この概念を正確に理解することが、適切な使い分けの第一歩となります。
1次元レイアウト: Flexbox
Flexboxは1次元レイアウトを制御するために設計されています。これは、行(横方向)か列(縦方向)のいずれか一方向にアイテムを配置することを意味します。
|
|
Flexboxでは、アイテムの配置は主軸に沿って行われます。折り返し(flex-wrap: wrap)を使用した場合でも、各行は独立して制御され、行間の列位置は揃いません。
2次元レイアウト: CSS Grid
CSS Gridは2次元レイアウトを制御するために設計されています。これは、行(横方向)と列(縦方向)の両方を同時に制御することを意味します。
|
|
CSS Gridでは、明示的にトラック(行と列)を定義し、アイテムをグリッドセル上に配置します。行間でも列位置が揃い、整然としたグリッドレイアウトを実現できます。
視覚的な違いを理解する
以下の図は、同じ5つのアイテムをFlexboxとCSS Gridでそれぞれ配置した場合の違いを示しています。
flowchart TB
subgraph flexbox["Flexbox(flex-wrap: wrap)"]
direction LR
subgraph row1["Row 1"]
F1["Item 1<br/>幅:200px"]
F2["Item 2<br/>幅:150px"]
F3["Item 3<br/>幅:180px"]
end
subgraph row2["Row 2"]
F4["Item 4<br/>幅:220px"]
F5["Item 5<br/>幅:160px"]
end
end
subgraph grid["CSS Grid(3列グリッド)"]
direction TB
subgraph grow1["Row 1"]
G1["Item 1"]
G2["Item 2"]
G3["Item 3"]
end
subgraph grow2["Row 2"]
G4["Item 4"]
G5["Item 5"]
G6[" "]
end
endFlexboxの特徴:
- 各アイテムのコンテンツに応じてサイズが決まる(コンテンツファースト)
- 行間で列位置が揃わない
- アイテム数に応じて柔軟に配置される
CSS Gridの特徴:
- グリッドトラックのサイズが先に決まる(レイアウトファースト)
- 行間で列位置が揃う
- 空のセルが生じることがある
それぞれが得意なレイアウトパターン
FlexboxとCSS Gridには、それぞれ得意とするレイアウトパターンがあります。具体例を通じて理解を深めましょう。
Flexboxが得意なパターン
パターン1: ナビゲーションバー
ナビゲーションバーは典型的な1次元レイアウトです。メニュー項目を横一列に並べ、ロゴとメニューの間にスペースを入れるといった配置はFlexboxの得意分野です。
|
|
|
|
Flexboxを選ぶ理由:
- 横一列に並べるだけの1次元レイアウト
space-betweenで左右に振り分ける配置が容易- メニュー項目数が変動してもレイアウトが崩れない
パターン2: カードのコンテンツ配置
カード内部のレイアウト(画像・タイトル・説明文・ボタン)は、縦方向の1次元レイアウトです。
|
|
|
|
Flexboxを選ぶ理由:
- 縦一列の1次元レイアウト
flex: 1とmargin-top: autoでコンテンツ量に関わらずボタンを最下部に固定- カードの高さが揃う際に内部コンテンツが柔軟に対応
パターン3: センタリング
要素を水平・垂直方向に中央揃えするケースは、Flexboxが最もシンプルに書けます。
|
|
Flexboxを選ぶ理由:
- たった3行で完全なセンタリングを実現
- 中央に配置する要素が1つの場合に最適
パターン4: 入力フォームのインライン配置
ラベル、入力フィールド、ボタンを横一列に並べるフォームレイアウトです。
|
|
|
|
Flexboxを選ぶ理由:
- 横一列の1次元レイアウト
- 入力フィールドを
flex: 1で伸縮させ、ボタンは固定幅を維持
CSS Gridが得意なパターン
パターン1: ページ全体のレイアウト
ヘッダー、サイドバー、メインコンテンツ、フッターで構成されるページレイアウトは、CSS Gridの代表的なユースケースです。
|
|
|
|
CSS Gridを選ぶ理由:
- 行と列を同時に制御する2次元レイアウト
grid-template-areasで視覚的にレイアウトを定義可能- 各エリアのサイズと位置を明示的に指定
パターン2: 画像ギャラリー
画像を格子状に整列させるギャラリーは、CSS Gridが最適です。
|
|
CSS Gridを選ぶ理由:
- 全ての画像を同じサイズのセルに配置
auto-fillとminmax()でレスポンシブに列数を調整- 行間で列位置が完全に揃う
パターン3: ダッシュボードUI
複数のウィジェットを配置するダッシュボードは、2次元的なレイアウト制御が必要です。
|
|
CSS Gridを選ぶ理由:
- 各ウィジェットが異なるサイズ(2列分、2行分など)を占める
- グリッドライン上に正確に配置
- 後からウィジェットの位置を変更しやすい
パターン4: フォームレイアウト
ラベルと入力フィールドを2列で整列させるフォームは、CSS Gridが適しています。
|
|
|
|
CSS Gridを選ぶ理由:
- ラベル列と入力列の幅を明示的に定義
- 全てのラベルが同じ幅で右揃え
- 行を追加してもレイアウトが維持される
選択の判断基準: 5つのチェックポイント
どちらを使うべきか迷った場合は、以下の5つのチェックポイントに従って判断してください。
チェックポイント1: 制御したい次元は1つか2つか
最も重要な判断基準です。
| 制御したい次元 | 推奨レイアウト手法 |
|---|---|
| 行または列のいずれか一方 | Flexbox |
| 行と列の両方を同時に | CSS Grid |
flowchart TD
A["レイアウト要件を分析"] --> B{"行と列を<br/>同時に制御する必要がある?"}
B -->|はい| C["CSS Gridを選択"]
B -->|いいえ| D{"要素を横一列または<br/>縦一列に並べる?"}
D -->|はい| E["Flexboxを選択"]
D -->|いいえ| F["要件を再分析"]チェックポイント2: コンテンツファーストかレイアウトファーストか
コンテンツファースト(Flexbox):
- コンテンツのサイズに応じてレイアウトを決める
- 「このナビゲーション項目がいくつあっても均等に配置したい」
- 「テキストの長さに応じてカラム幅を調整したい」
レイアウトファースト(CSS Grid):
- 先にレイアウト(列数・行数・サイズ)を決め、そこにコンテンツを配置する
- 「3列のグリッドを作り、各セルに画像を配置したい」
- 「サイドバーは250px固定、メインコンテンツは残り全部」
チェックポイント3: 行間で列位置を揃える必要があるか
揃える必要がある場合: CSS Grid
|
|
揃える必要がない場合: Flexbox
|
|
チェックポイント4: 配置がアイテムの順序に依存するか
順序に依存する場合: Flexbox
- アイテムは自然な順序で流れるように配置される
- 追加されたアイテムは末尾に配置される
順序に依存しない場合: CSS Grid
grid-columnとgrid-rowで任意の位置に配置可能- アイテムをグリッド上の特定のセルに直接配置
チェックポイント5: 空のスペースをどう扱うか
空のスペースをアイテム間に分配: Flexbox
|
|
空のセルをそのまま維持: CSS Grid
|
|
FlexboxとGridを組み合わせる実践パターン
実際のWebサイトでは、FlexboxとCSS Gridを組み合わせて使用することが一般的です。ページ全体はGridで構成し、個々のコンポーネント内部はFlexboxで制御するアプローチが効果的です。
パターン1: Gridレイアウト + Flexboxカード
ページ全体をCSS Gridで構成し、各カードの内部はFlexboxで制御します。
|
|
|
|
組み合わせの利点:
- CSS Grid: カードを格子状に整列させ、レスポンシブに列数を調整
- Flexbox: カードの高さが揃った状態で、内部コンテンツを柔軟に配置
flowchart TB
subgraph page["ページ構造"]
subgraph grid["CSS Grid(カードの配置)"]
subgraph card1["Card 1"]
direction TB
C1I["Image"]
C1B["Body<br/>flex: 1"]
C1L["Link"]
end
subgraph card2["Card 2"]
direction TB
C2I["Image"]
C2B["Body<br/>flex: 1"]
C2L["Link"]
end
subgraph card3["Card 3"]
direction TB
C3I["Image"]
C3B["Body<br/>flex: 1"]
C3L["Link"]
end
end
end
style card1 fill:#e3f2fd
style card2 fill:#e3f2fd
style card3 fill:#e3f2fdパターン2: Gridページレイアウト + Flexboxヘッダー
ページ全体のレイアウトはCSS Gridで、ヘッダー内部のナビゲーションはFlexboxで制御します。
|
|
|
|
パターン3: ネストしたGridとFlexbox
複雑なダッシュボードUIでは、複数レベルでGridとFlexboxを組み合わせます。
|
|
よくある設計ミスと改善方法
ミス1: 2次元レイアウトをFlexboxで無理に実現
問題のあるコード:
|
|
問題点:
- 計算式が複雑でメンテナンスしにくい
- 最終行のアイテムが3つ未満の場合、意図しない配置になる
- ガター(間隔)の調整が難しい
改善したコード:
|
|
ミス2: 単純な横並びにCSS Gridを使用
問題のあるコード:
|
|
問題点:
- ナビゲーション項目数が変わると
grid-template-columnsも変更が必要 - 単純な横並びにはGridは冗長
改善したコード:
|
|
ミス3: FlexboxとGridの混在による意図しない挙動
問題のあるコード:
|
|
改善方針:
- 1つの要素に対してFlexboxかGridのいずれか1つだけを適用する
- 異なるレイアウト手法が必要な場合は、ラッパー要素を追加する
ミス4: レスポンシブ対応の不足
問題のあるコード:
|
|
改善したコード:
|
|
判断フローチャート
どちらを使うべきか迷った場合は、以下のフローチャートに従って判断してください。
flowchart TD
Start["レイアウト要件を確認"] --> Q1{"行と列の両方を<br/>同時に制御する?"}
Q1 -->|はい| Grid1["CSS Grid"]
Q1 -->|いいえ| Q2{"要素を一方向に<br/>並べるだけ?"}
Q2 -->|はい| Flex1["Flexbox"]
Q2 -->|いいえ| Q3{"行間で列位置を<br/>揃える必要がある?"}
Q3 -->|はい| Grid2["CSS Grid"]
Q3 -->|いいえ| Q4{"コンテンツのサイズに<br/>応じてレイアウトを<br/>調整する?"}
Q4 -->|はい| Flex2["Flexbox"]
Q4 -->|いいえ| Q5{"レイアウトを先に決めて<br/>コンテンツを配置する?"}
Q5 -->|はい| Grid3["CSS Grid"]
Q5 -->|いいえ| Flex3["Flexbox"]
Grid1 --> Result1["grid-template-areas<br/>grid-template-columns<br/>grid-template-rows"]
Grid2 --> Result2["repeat + auto-fill/fit<br/>minmax()"]
Grid3 --> Result3["明示的なトラック定義"]
Flex1 --> Result4["flex-direction<br/>justify-content<br/>align-items"]
Flex2 --> Result5["flex-grow<br/>flex-shrink<br/>flex-basis"]
Flex3 --> Result6["gap + flex-wrap"]まとめ
FlexboxとCSS Gridは、それぞれ異なる強みを持つレイアウト手法です。以下のポイントを押さえて、適切に使い分けましょう。
| 比較項目 | Flexbox | CSS Grid |
|---|---|---|
| 次元 | 1次元(行または列) | 2次元(行と列) |
| 設計思想 | コンテンツファースト | レイアウトファースト |
| 得意なレイアウト | ナビゲーション、センタリング、カード内部 | ページレイアウト、ギャラリー、ダッシュボード |
| アイテムサイズ | コンテンツに依存 | トラック定義に依存 |
| 行間の列揃え | 揃わない(各行独立) | 揃う |
選択の基本指針:
- 1次元レイアウト(横一列・縦一列) → Flexbox
- 2次元レイアウト(行と列を同時制御) → CSS Grid
- コンテンツ量に応じた柔軟な配置 → Flexbox
- 事前に決めたレイアウトへの配置 → CSS Grid
- 両者を組み合わせる → ページ全体はGrid、コンポーネント内部はFlex
実際のWebサイト開発では、FlexboxとCSS Gridを適材適所で組み合わせることが一般的です。それぞれの特性を理解し、レイアウト要件に応じて最適な手法を選択してください。