「GridとFlexboxってどう使い分ければいいの?」という疑問をよく耳にします。
簡単に言うと、Flexboxは「1方向(行か列)」のレイアウト、Gridは「縦横2方向」のレイアウトに向いています。この記事では、実際のWeb制作でよく使うCSS Gridのパターンをプレビュー+コード付きでまとめました。
この記事でわかること
- CSS Gridの基本(等幅カラム・自動折り返し)
- セルの結合・名前付きエリアの使い方
- 複雑なサイトレイアウトの組み方
- レスポンシブ対応(@media切り替え・auto-fill)
CSS Gridとは?
CSS Grid(グリッド)は、縦横2方向のグリッド(格子状の枠)を定義してレイアウトを組む手法です。親要素に display: grid を指定すると、子要素をグリッドのセルに自動で配置できます。
| 用語 | 説明 |
|---|---|
| Gridコンテナ | display: grid を指定した親要素 |
| Gridアイテム | Gridコンテナの直接の子要素 |
| fr(フラクション) | 余ったスペースを比率で分割する単位。1fr 2fr なら 1:2 で分割 |
| グリッドライン | 列・行を区切る境界線。1から番号が振られる |
| gap | セルとセルの間の隙間 |
基本パターン編
等幅カラム(repeat + fr)
最も基本的なグリッド。repeat(3, 1fr) で「3列・均等幅」を定義する。fr は余ったスペースを比率で分割する単位。
<div class="grid"> <div>アイテム A</div> <div>アイテム B</div> <div>アイテム C</div> <div>アイテム D</div> <div>アイテム E</div> <div>アイテム F</div> </div>
.grid { display: grid; /* グリッドレイアウトを有効化する */ grid-template-columns: repeat(3, 1fr); /* 3列・各列が均等幅(frは余白を比率で分割する単位) */ gap: 12px; /* セルどうしの縦横の隙間を12pxに設定 */ }
自動折り返しカード(auto-fill + minmax)
親幅に応じて列数が自動で増減するレスポンシブカードグリッド。auto-fill でできるだけ多くの列を並べ、minmax(200px, 1fr) で最小幅200px・余白は均等分配する。
<div class="card-grid"> <div class="card">カード A</div> <div class="card">カード B</div> <!-- ...続く --> </div>
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* auto-fill → 親幅に収まる限り、できるだけ多くの列を並べる */ /* minmax(200px, 1fr) → 最小幅200px、最大は余白を均等に伸ばす */ /* → 幅が広ければ多列、狭ければ少列に自動で変わる */ gap: 16px; }
セルの結合(grid-column / grid-row)
特定のセルを複数列・複数行にまたがらせるパターン。grid-column: span 2 で「2列分の幅を占有」を指定する。ダッシュボードや特集記事に使う。
grid-column: span 2 / grid-row: span 2
<div class="grid"> <div class="big">横2列 × 縦2行</div> <div>C</div> <div>D</div> <div class="wide">横2列</div> <div>F</div> </div>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 120px; /* 自動生成される行の高さを120pxに設定 */ gap: 10px; } .big { grid-column: span 2; /* 横方向に2列分の幅を占有する */ grid-row: span 2; /* 縦方向に2行分の高さを占有する */ } .wide { grid-column: span 2; /* 横方向だけ2列分の幅を占有する */ }
レイアウト応用編
名前付きエリア(grid-template-areas)
グリッドの各エリアに名前をつけてレイアウトを定義する。CSSだけでページ構造が一目でわかり、メンテナンスしやすい。サイト全体のレイアウトに最適。
<body class="layout"> <header>ヘッダー</header> <nav class="sidebar"> <p>概要</p> <p>プロジェクト</p> <p>設定</p> </nav> <main>メインコンテンツ</main> <footer>© 2025 My Site</footer> </body>
.layout { display: grid; grid-template-columns: 200px 1fr; /* サイドバー200px固定、メインが残りを占有 */ grid-template-rows: 60px 1fr 50px; /* ヘッダー60px、メイン可変、フッター50px */ min-height: 100vh; /* 最低でも画面の高さ全体を確保する */ grid-template-areas: "header header" /* 1行目:ヘッダーが2列すべてを占有 */ "sidebar main" /* 2行目:左にサイドバー、右にメイン */ "footer footer"; /* 3行目:フッターが2列すべてを占有 */ } header { grid-area: header; } /* "header" エリアに配置する */ .sidebar { grid-area: sidebar; } /* "sidebar" エリアに配置する */ main { grid-area: main; } /* "main" エリアに配置する */ footer { grid-area: footer; } /* "footer" エリアに配置する */
異なる列幅の混在(fr + px + auto)
固定幅・自動幅・可変幅を混在させるパターン。200px 1fr auto のように単位を混ぜることができる。サイドバー固定・メイン可変・ボタン幅自動などに使う。
左ナビ(固定)
メイン(残りを占有)
ボタン(中身の幅)
<body class="layout"> <nav>左ナビ(200px)</nav> <main>メインコンテンツ(残りを占有)</main> <button>+ 新規作成</button> </body>
.layout { display: grid; grid-template-columns: 200px 1fr auto; /* 200px → 左カラムを200pxに固定する */ /* 1fr → 中央カラムが残りのスペースをすべて占有して伸縮する */ /* auto → 右カラムは内側のコンテンツの幅に合わせて自動調整 */ gap: 16px; }
行の高さ指定(grid-template-rows)
列だけでなく行の高さも明示的に指定できる。grid-template-rows で各行の高さを定義する。ヘッダー・メイン・フッターの高さを決めたいときに使う。
<body class="grid"> <header>ヘッダー(60px)</header> <div class="content">コンテンツ A</div> <div class="content">コンテンツ B</div> <div class="content">コンテンツ C</div> <footer>フッター(50px)</footer> </body>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: 60px 1fr 50px; /* 1行目60px・2行目可変・3行目50px */ min-height: 100vh; /* 1fr を機能させるため高さを確保 */ gap: 8px; } header { grid-column: span 3; } /* ヘッダーは3列すべてにまたがる */ footer { grid-column: span 3; } /* フッターは3列すべてにまたがる */
配置コントロール編
セル内の配置(justify-items / align-items)
グリッドセルの内側でのアイテムの配置を制御するパターン。justify-items で水平方向、align-items で垂直方向の揃えを全セルに一括指定できる。個別に変えたい場合は justify-self / align-self を使う。
左上
中央
右下
引き伸ばし
<div class="grid"> <div class="cell cell-start"> <div class="item">start(左上)</div> </div> <div class="cell cell-center"> <div class="item">center(中央)</div> </div> <div class="cell cell-end"> <div class="item">end(右下)</div> </div> <div class="cell cell-stretch"> <div class="item">stretch(引き伸ばし)</div> </div> </div>
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; justify-items: center; /* 水平方向:start / center / end / stretch */ align-items: center; /* 垂直方向:start / center / end / stretch */ } /* 個別セルだけ変えたい場合は justify-self / align-self を使う */ .special { justify-self: end; /* このセルだけ右揃えにする */ align-self: start; /* このセルだけ上揃えにする */ }
ライン番号での配置(grid-column: 1 / 3)
グリッドのライン番号を直接指定してセルを配置するパターン。grid-column: 1 / 3 は「1番ラインから3番ラインまで=2列分」を意味する。複雑なレイアウトや特集枠に使う。
grid-column: 1/3 · grid-row: 1/3
<div class="grid"> <div class="feature">🌟 特集記事</div> <div>記事 A</div> <div>記事 B</div> <div class="wide">ワイド記事</div> <div>記事 C</div> <div>記事 D</div> <div>記事 E</div> <div>記事 F</div> </div>
.grid { display: grid; grid-template-columns: repeat(4, 1fr); /* 4列・均等幅 */ grid-auto-rows: 120px; /* 自動生成される行の高さを120pxに設定 */ gap: 10px; } .feature { grid-column: 1 / 3; /* 列:1番ラインから3番ラインまで(= 2列分の幅) */ grid-row: 1 / 3; /* 行:1番ラインから3番ラインまで(= 2行分の高さ) */ } .wide { grid-column: 3 / 5; /* 列:3番ラインから5番ラインまで(= 2列分の幅) */ }
隙間を自動で埋める(grid-auto-flow: dense)
大きいセルの隙間を後続のセルで自動的に埋めるパターン。grid-auto-flow: dense を指定すると、余白をなるべく詰めるように配置される。画像ギャラリーに最適。
<div class="gallery"> <div class="large">🖼 大きい画像</div> <div>画像 A</div> <div>画像 B</div> <div class="tall">縦長</div> <div>画像 C</div> <div>画像 D</div> <div>画像 E</div> </div>
.gallery { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; /* 基準となる行の高さを150pxに設定 */ grid-auto-flow: dense; /* 大きいセルが空けた隙間に後続セルを自動で詰める */ gap: 10px; } .large { grid-column: span 2; /* 横方向に2列分の幅を占有する */ grid-row: span 2; /* 縦方向に2行分の高さを占有する */ } .tall { grid-row: span 2; /* 縦方向だけ2行分の高さを占有する */ }
レスポンシブ対応編
レスポンシブ:@media で列数を切り替え
PCでは3列、スマートフォンでは1列に切り替えるパターン。@media で grid-template-columns を上書きするだけで実現できる。auto-fill + minmax を使えば @media なしで対応可能なケースも多い。
<div class="grid"> <section> <h2>セクション A</h2> <p>コンテンツ A の内容をここに書きます。</p> </section> <section> <h2>セクション B</h2> <p>コンテンツ B の内容をここに書きます。</p> </section> <section> <h2>セクション C</h2> <p>コンテンツ C の内容をここに書きます。</p> </section> </div>
/* PC:3列 */ .grid { display: grid; grid-template-columns: repeat(3, 1fr); /* 3列・均等幅 */ gap: 24px; } /* スマホ:1列 */ @media (max-width: 768px) { .grid { grid-template-columns: 1fr; /* 1列に変更するだけ */ gap: 16px; } }
/* @media 不要・自動でレスポンシブ対応 */ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); /* auto-fill → 親幅に収まる限りできるだけ多く列を並べる */ /* minmax(280px, 1fr) → 最小280px・最大は均等に広げる */ /* → 幅が狭まると自動で列数が減るため @media が不要 */ gap: 24px; }
まとめ
- 基本は
display: grid+grid-template-columns+gap frは余ったスペースを比率で分割する単位。1frで均等幅auto-fill + minmax()でレスポンシブなカードグリッドが @media なしで作れるgrid-column: span Nでセルを複数列・行にまたがらせるgrid-template-areasで名前付きエリアを使うとレイアウトの見通しが良くなるgrid-auto-flow: denseでギャラリーの隙間を自動で埋められる
CSS GridはFlexboxと組み合わせることでより柔軟なレイアウトが作れます。大枠のページ構成にはGrid、その中の要素の並べ方にはFlexboxを使うのが定番の組み合わせです。