CSS Grid と Flexbox の違い

CSSのレイアウトシステムにはGridFlexboxの2つがあります。結論から言うと:

  • Flexbox: 1方向(横 or 縦)のレイアウトに最適
  • Grid: 2方向(横と縦)のレイアウトに最適

比較表

項目FlexboxGrid
方向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-fillminmax の組み合わせで、メディアクエリなしでレスポンシブなグリッドが作れます。

フォームレイアウト

.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. 1方向のレイアウト? → Flexbox
  2. 2方向のレイアウト? → Grid
  3. コンテンツサイズに合わせたい? → Flexbox
  4. 固定のグリッド構造に合わせたい? → Grid
  5. どちらでもいけそう? → 好みでOK(併用も可)

まとめ

パターン推奨
ナビバー、ボタン並びFlexbox
カードグリッドGrid
ページ全体のレイアウトGrid
カード内の縦並びFlexbox
フォームのラベル+入力Grid
中央揃えFlexbox or Grid

Flexbox と Grid はどちらか一方ではなく、組み合わせて使うのが現代のCSS開発です。迷ったらまず Flexbox で試し、2次元の配置が必要になったら Grid に切り替えましょう。


CSSのpx・rem・em変換には、Assistyのpx変換ツールが便利です。ブラウザ上で単位変換を素早く計算できます。