CSS設計

FlexboxとCSS Grid、どちらを使うべきか

読了 6分
CSS設計

FlexboxとCSS Grid、どちらを使うべきか

レイアウトを組むたびに「これFlexboxとGridどっちで組むのが正解なんだろう」と毎回迷っていたので、自分の中で整理したときのメモです。

結論から言うと、両者は競合する技術ではなくて、得意な次元が違う だけのようです。この違いを押さえると、判断はかなり機械的にできるようになりました。

まず「1次元のFlexbox、2次元のGrid」

ざっくりした使い分けの軸は1つだけです。

  • Flexbox … 1方向(行 または 列)に並べる
  • Grid … 行 列の両方を同時に制御する

ボタンを横並びにする、ナビゲーションを等間隔に置く、アイコンとテキストを縦中央で揃える。こうした「1列に並べる」用途はFlexboxの独壇場です。一方、カードを格子状に並べる、ページ全体をヘッダー・サイド・メインに区切る、といった「縦横の構造」がある場面はGridが向いています。

Flexboxが向く例

要素を1方向に並べて、間隔や寄せ方を調整するケースです。こんな感じです。

.toolbar {
  display: flex;
  align-items: center; /* 縦方向の中央揃え */
  gap: 12px; /* 要素間の余白 */
}

.toolbar .spacer {
  margin-left: auto; /* これ以降を右端へ押し出す */
}

margin-left: auto で「ここから先を右に寄せる」といった融通の利く制御ができるのはFlexboxならではです。要素数が可変で、中身の幅に応じて自然に詰めたい場合もFlexboxが扱いやすいです。

Gridが向く例

行と列の構造をはっきり持たせたいときはGridです。レスポンシブなカード一覧は典型例です。

.cards {
  display: grid;
  /* 最小240px・余れば伸びる列を、入るだけ自動で並べる */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

auto-fillminmax() を組み合わせると、メディアクエリを書かなくても画面幅に応じて列数が変わります。これはFlexboxだけでは素直に書けない、Gridの強みです。初めて使ったとき、メディアクエリが要らないのに感動しました。

ページ全体の骨組みも、エリア名を使うとGridで読みやすく定義できます。

.layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-areas:
    'header header'
    'sidebar main';
}
.layout > header {
  grid-area: header;
}
.layout > aside {
  grid-area: sidebar;
}
.layout > main {
  grid-area: main;
}

入れ子で組み合わせるのが実戦的

実際のUIでは「どちらか一方」ではなくて、Gridで全体を区切り、その中の各セルをFlexboxで整える という組み合わせが多くなります。たとえばカード一覧はGrid、各カードの中の「タイトル・本文・フッターの縦並び」はFlexbox、という具合です。

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}
.card {
  display: flex;
  flex-direction: column; /* カード内は縦並び */
}
.card .footer {
  margin-top: auto; /* フッターを下端に固定 */
}

margin-top: auto で高さの違うカードでもフッターをきれいに下揃えできます。これはFlexboxが得意とするところです。これは便利。

迷ったときの判断

迷ったときは次の順で考えると決めやすいです。

質問はいいいえ
行と列の両方を制御したい?Grid次へ
要素を1方向に並べたいだけ?Flexbox場合による

「全体の骨組み=Grid、部分の整列=Flexbox」をデフォルトにしておくと、ほとんどのレイアウトは素直に組めます。自分はこれで迷うことがだいぶ減りました。

まとめ

  • 1次元(行か列)はFlexbox、2次元(行と列)はGrid
  • レスポンシブな格子は auto-fill + minmax() のGridが楽
  • 実戦ではGridで区切り、Flexboxで中身を整える組み合わせが強い

両者の細かいプロパティはMDNのCSS Gridガイドにも整理されています。まずは「次元」で選ぶ習慣をつけてみるとよさそうです。以上です。