CSSのgridレイアウトで要素を格子状に並べる基本(display: grid)

flexbox が 1 次元(横または縦の一方向)のレイアウトに強いのに対し、CSS Grid は 2 次元(行と列を同時に)制御できるレイアウトシステムだ。カード一覧やダッシュボードのような格子状の配置に威力を発揮する。

基本のグリッド

親要素に display: grid を指定し、grid-template-columns で列の構成を定義する。

HTML
CSS
JavaScript
<div class="grid-demo">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
</div>
.grid-demo {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 12px;
}
.cell {
  background: #6366f1;
  color: #fff;
  padding: 20px;
  border-radius: 6px;
  text-align: center;
  font-weight: bold;
}

1fr 1fr 1fr で等幅 3 列のグリッドを作成している。fr は fraction(比率)の略で、利用可能なスペースを分け合う単位だ。6 つの子要素が自動的に 3 列 × 2 行に配置される。

repeat() で繰り返しを簡略化する

列数が多いとき、毎回 1fr を書くのは冗長になる。repeat() を使えば同じ指定を繰り返せる。

/* 3列の等幅グリッド */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

repeat(3, 1fr)1fr 1fr 1fr と同じ意味だ。列数を変えたいときに数字を 1 か所変えるだけで済むため、保守性が高い。

固定幅と可変幅の組み合わせ

fr と固定値を混ぜることで、サイドバー付きレイアウトなども簡単に実現できる。

HTML
CSS
JavaScript
<div class="layout">
  <div class="side">sidebar (200px)</div>
  <div class="content">main (1fr)</div>
</div>
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 16px;
  font-size: 14px;
}
.side {
  background: #e2e8f0;
  padding: 16px;
  border-radius: 6px;
}
.content {
  background: #dbeafe;
  padding: 16px;
  border-radius: 6px;
}

サイドバーが固定 200px、メインコンテンツが残りの幅を占めるレイアウトだ。flexbox でも同様のことは可能だが、grid のほうが宣言的でわかりやすい。

grid-template-rows で行の高さを制御する

列だけでなく行も明示的に定義できる。ヘッダー・メイン・フッターのようなページ全体の構成に使うことが多い。

.page {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 60px 1fr 40px;
  min-height: 100vh;
}

ヘッダー 60px、フッター 40px を固定し、メインコンテンツが残りの高さを占める。min-height: 100vh と組み合わせることで、画面いっぱいのレイアウトになる。

gap で間隔を指定する

grid の gap は行間と列間を一括で指定できる。行間と列間を別々にしたいときは、row-gap と column-gap を個別に使う。

gap: 16px

行間・列間ともに 16px。ほとんどの場合はこれで十分だ。

row-gap: 24px / column-gap: 12px

行間は広め、列間は狭めにしたいときに使い分ける。カードリストで行間にゆとりを持たせたい場合などに有効。

auto-fill と auto-fit でレスポンシブ対応する

列数を固定せず、コンテナの幅に応じて自動的に列数を変えたいときは、repeat() の中で auto-fill または auto-fit を使う。

.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

minmax(200px, 1fr) は「最小 200px、最大 1fr」という意味で、コンテナ幅が広ければ列が増え、狭ければ列が減る。メディアクエリを書かなくてもレスポンシブなグリッドが実現する。

auto-fill

空きスペースがあっても列のトラックを確保し続ける。要素が少ないときに空の列スペースが残る。

auto-fit

要素が埋まらない列トラックを折りたたんで、既存の要素を引き伸ばす。要素数が少ないときにスペースを有効活用したい場合に向いている。

flexbox との使い分け

flexbox も grid もレイアウトの道具であり、どちらかが優れているわけではない。特徴を理解して使い分けるのが大切だ。

観点flexboxgrid
次元1 次元(行 or 列)2 次元(行 and 列)
得意ナビバー、ツールバーカード一覧、ダッシュボード

ナビゲーションバーのように 1 方向に要素を並べるだけなら flexbox がシンプルだ。一方、行と列の両方を意識するレイアウトでは grid のほうが直感的に書ける。実務では両者を組み合わせて使うのが一般的で、ページ全体の骨格を grid で作り、各セクション内の要素配置を flexbox で行うパターンが定番になっている。