今回の記事では、CSSのGrid Layoutについて分かりやすく解説します。
一見複雑そうに感じるGridですが、ポイントを押さえれば決して難しくありません。
基本をマスターすれば、複雑なレイアウトもすぐに組めるようになります。
サンプルや図を交えて、丁寧に解説していきますので、一緒にGridの使い方を身につけていきましょう。
CSS Gridとは?
gridとは
CSSの「grid(グリッド)」とは、2次元のレイアウトを実現するためのCSSレイアウトシステムです。
「grid」は本来「格子」「網」「碁盤の目」という意味で、ウェブ制作では行(row)と列(column)で構成されるレイアウトを簡単に実装できるのが最大の特徴です。
表計算ソフトとかを思い浮かべるといいかもしれません。
従来のCSSレイアウト(floatやposition、Flexboxなど)では、複雑な2次元レイアウトを組むのが難しく、テクニックや工夫が必要でした。
CSS Gridを使うことで、「3列×2行のレイアウト」や「セルをまたぐ配置」「入れ子構造」など、複雑な配置をシンプルな記述でコントロールできるようになります。
tableとの違い
まず、「行」と「列」といえば tableタグを思い浮かべる方もいるかもしれませんが、tableタグは「データ表」をマークアップする役割である一方、CSSのGridはレイアウトやデザインを組むために使用する役割となり、用途が全く異なります。
また、CSSの displayプロパティには table もあります。display: table;
display: gridとdisplay: table は似ている部分もありますが、用途・柔軟性・推奨される使い方が大きく異なります。
| display: grid | display: table | |
|---|---|---|
| レイアウト | 2次元のグリッド | 表形式のレイアウト |
| 自由度 | 高い(行・列を自由に設計) | 行・列は自動調整される |
| レスポンシブ | 容易 | 難しい |
| 用途 | モダンなページレイアウト全般 | 表現をテーブル的にしたい時 |
| 子要素指定 | grid-row/grid-column | table-row/table-cell |
以前はこの display: table; はFlexboxやGridがなかった時代によく使われていました。
現在はレイアウト目的には「grid」や「flex」推奨です。
ただし、「表形式の見た目」やIE8以前への互換性が必要な場合のみdisplay: tableの出番となります。
Flexbox(display: flex)との違い
Flexbox(フレックスボックス)も人気の高いレイアウト方法ですが、Flexboxは“1次元”のレイアウトに特化しています。
つまり、Flexboxは「横並び」や「縦並び」など一方向の並び替えや整列には強いですが、行・列の両方を同時に制御することは苦手です。
一方で、CSS Gridは「行」と「列」を同時に指定できるため、“2次元”のレイアウトが簡単に実現できます。
- Flexbox:1次元の並び(横 or 縦)
- Grid :2次元の複雑なレイアウト(表のような配置)
図解-1.png)
用途に応じて使い分けることで、レイアウトの実装効率が大きく向上します。
Flexboxについては下記で詳しく書いてますのでご確認ください。
gridの基本構文と主要プロパティ
CSS Gridを利用するには、まず親要素(コンテナ)にdisplay: grid;を指定します。
これで、その子要素が自動的にグリッドのアイテムとして扱われます。
ここからまずは gridの基本プロパティを抑えましょう。
grid-template-columnsとは
grid-template-columnsは、グリッドの「列(columns)」の数と幅を指定するプロパティです。
下記のソースコードの例では3列のレイアウトになります。
.container {
display: grid;
grid-template-columns: 200px 1fr 2fr;
}

200px:1列目の幅は固定200px1fr:2列目は残りのスペース分の比率を1とする2fr:3列目は残りのスペース分の比率を2とする(2倍分)
frは「fraction(分割単位)」という意味になります。
上記の図のように、例えば親要素の幅が800pxあったとすると、各カラムの幅は以下のように計算されます。
1.まず1列目(左端)が「200px」で固定され残りのスペースが生まれます。
(1列目):200px
(残りのスペース)=800px(親の幅)− 200px(1列目)=600px
2. 残りのスペースを「1fr」と「2fr」に分ける
(2列目):1fr
(3列目):2fr
という合計「3fr」分で割り振ることになります。
600px ÷ 3fr = 200px / fr
3. 実際の幅
1fr分が200pxというのが決まれば、それを各カラムのfr分で割当てます。
1fr = 200px × 1 = 200px
2fr = 200px × 2 = 400px
grid-template-rowsとは
grid-template-rowsは、グリッドの「行(row)」の数と高さを指定するプロパティです。
下記のソースコードの場合は3行表示になります。
.container {
display: grid;
grid-template-rows: 100px auto 2fr;
}
- 1行目:固定100px
- 2行目:auto 内容に応じて自動調整(ここでは仮に20pxとします)
- 3行目:2fr 残りのスペース(280px)

3列目は2frなのに「2倍」の560px ではないのか?
ここで疑問に思われたかとおもいますが、3行目は2frとなっていますが、残りの280px分となっています。これは次の計算式によるものになります。
(残りのスペース)= 400px – 100px – 20px = 280px
(3行目):2fr
のため、残りのスペースを「合計2fr分」で割り振ることになります。
280px ÷ 2fr = 140px / fr
2fr = 140px × 2 = 280px
このため、3行目の2frは1frと書いても同じ横幅となります。
grid gapとは
グリッドのアイテム同士のすき間(間隔)を設定するプロパティがgapです。
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 70px 70px;
gap: 16px;
}
gap: 16px;→ 行・列の間に16pxのすき間をつけるgap: 行 列;のように、行と列で値を分けることも可能(例)gap: 16px 5px
この例では、
grid-template-columns: 1fr 1fr 1fr; で3列、
grid-template-rows: 70px 70px; で2行のレイアウトを作成しています。
その要素の黒塗りの箇所が gap 16px; で設定した要素と要素のすき間となります。

Gridの位置揃え(全体・セル内)
grid全体を中央寄せ(横方向のみ)
gridに限らずサイト全体で中央寄せ表示するにはmargin: 0 auto; を指定します。
- margin: 0 auto; で中央寄せします。
- grid に幅(width)を指定します。
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 70px 70px;
gap: 16px;
margin: 0 auto; /* 水平方向の中央寄せ */
width: 800px; /* 横幅を指定 */
}
セル内を右寄せ・中央・左寄せ・上段・中央・下段に配置する
- 親要素で一括で指定する場合は、justify-items(横) や align-items(縦)を利用します。
- 子要素(セル)を個別で設定する場合は、justify-self(横) や align-self(縦)を利用します。
設定値はどちらも同じです。デフォルト値は stretch (セル全体に広がる)になっています。
justify-self … 横方向の位置(start/center/end/stretch など)
align-self … 縦方向の位置(start/center/end/stretch など)
/*セル内を中央寄せにする(一括) */
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
justify-items: center;
align-items: center;
}
/* 個別で設定する */
.item cell-left{
justify-self: end;
}
各設定値は以下の図のとおりです。

※「stretch」(デフォルト)の場合、アイテム自体はセル全体に広がりますが、テキストの位置は上詰めです。
セル内のテキスト表示を中央にしたい場合は、追加でtext-align: center;や、display: flexなどを入れて中央にします。
以下は中央寄せにする2つの方法のサンプルコードです。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 150px;
/* 指定がなければ stretch */
/* justify-items: stretch; */
/* align-items: stretch; */
}
/* 左のstretch 中央寄せ*/
.item {
background: #8e24aa;
display: flex;
align-items: center;
justify-content: center;
}
/* 右のstretch 中央寄せ*/
.item2 {
background: #8e24aa;
justify-self: center;
align-self: center;
}
- 左は、親要素の grid デフォルトの「stretch」が効いており、セル全体に広がった.itemに対して、子要素で「display: flex;」を設定し、Flexboxで中のテキストを中央寄せにしています。
- 右は、親要素からの「stretch」を「justify-self: center」などで上書きして、.item2 自体がセルの中央に配置されています。(アイテム自体の幅・高さは内容サイズのまま)

少しややこしい箇所ですが、挙動の違いが確認できたと思います。
grid css span(配置と大きさ)
グリッドアイテムが複数の行や列にまたがって配置できるのが、Gridの強力な特徴です。
拡張したい子要素にspanを入れると列や行にまたがって表示されます。
.item1 {
grid-column: span 2; /* 2線分またがる */
grid-row: span 3; /* 3行分またがる */
}
grid-column: 1 / 3;(1線目から3線目(2列分))という書き方も可能- 表組みやレイアウト調整でよく使われます
| 指定例 | 効果 |
|---|---|
grid-column: span 2; | 右へ2線分またがる |
grid-row: span 3; | 下へ3行分またがる |
grid-column: 2 / 4; | 2線目から4線目まで(2列分) |
grid-row: 1 / 3; | 1行目から3行目まで(2行分) |
grid-area: 1 / 1 / 3 / 3; | 1行1線目から3行3線目まで(2行×2列分) |
grid-area: 2 / 2 / 4 / 4; | 2行2線目から4行4線目まで(2行×2列分) |
このように開始地点、終了地点を指定できるので、gridでは自由な配置と、その大きさを自由に設定することが可能になっています。
開始地点で配置、終了地点で大きさが設定できると考えると覚えやすいかと思います。
grid-areaの指定方法・注意点
grid-area: 行開始 / 列開始 / 行終了 / 列終了; の形式
例えば grid-area: 1 / 1 / 3 / 3; は「1行1列目の線から始まり、3行目・3列目の線で終わる」
注意点は線であることです。
以下は指定方法のサンプル図です。数値がセルを分ける枠線の番号となっています。
例えば下記のdiv1grid-area: 1 / 1 / 3 / 3; の場合は「1行1列目から3行3番目の線まで」が大きさになり、div2は grid-area: 1 / 3 / 4 / 4 ; の場合は「1行の3列線から4行の4列線まで」の大きさになります。
div3 grid-area: 3 / 1 / 5 / 3; の場合は、「3行目1列線から、5行の3列線まで」の大きさ、となります。

※ 余談ですが、この図はGoogle Chromeの開発者ツールからソースに出てくるgridの箇所をクリックすると表示されます。

コードは以下です。
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr ; /* 3列 */
grid-template-rows: 60px 60px 60px 60px ; /* 4行 */
}
.div1 { grid-area: 1 / 1 / 3 / 3; background: #ec407a; }
.div2 { grid-area: 1 / 3 / 4 / 4; background: #26a69a; }
.div3 { grid-area: 3 / 1 / 5 / 3; background: #ffb300; }
.div4 { grid-area: 4 / 3 / 5 / 4; background: #78909c; }
すこしややこしいですね…
複雑なレイアウトほど grid-area の数値指定はミスもしやすく、直感的にも分かりにくくなりがちです。
そんな時、視覚的にレイアウトを設計できる grid-template-areas という便利な方法があります。次のコンテンツで解説します。
gridのプロパティ応用例
grid-template-areasでセルに名前をつける
grid-template-areasで各セルに名前を付けていき、各子要素にgrid-areaで「エリア名」を割り当てて配置します。
HTMLやCSSを読むだけで、全体のレイアウト構造が直感的に分かるメリットがあります。
先ほど、ややこしかった grid-area の結合がコードレベルで分かりやすくなりますよ。
まずはコードをご確認下さい。
<div class="container">
<div class="item header">Header</div>
<div class="item sidebar">Sidebar</div>
<div class="item main">Main</div>
<div class="item footer">Footer</div>
</div>
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr ; /* 3列 */
grid-template-rows: 60px 60px 60px 60px ; /* 4行 */
grid-template-areas:
"header header sidebar"
"header header sidebar"
"main main sidebar"
"main main footer";
}
.header { grid-area: header; background: #ec407a; }
.sidebar { grid-area: sidebar; background: #26a69a; }
.main { grid-area: main; background: #ffb300; }
.footer { grid-area: footer; background: #78909c; }

grid-template-areas:
"header header sidebar"
"header header sidebar"
"main main sidebar"
"main main footer";
}
grid-template-areas:でセルに名前付けをして、grid-area でその名前を割当てすれば先ほどと同じ表が作られます。
ソースコード上でも大変見やすいですね。
なお、grid-template-areasに指定するheaderやmainなどの名前には特に厳密な命名規則はありません。(「.」(ドット)は不可です)
今回付けたheaderとかの名前は、あくまでサンプルなので、意味はありませんのでご了承下さい…
repeatの活用
Gridでは同じパターンを繰り返す場合、repeat()関数が非常に便利です。
repeat(3, 1fr); は、1fr 1fr 1fr; と同じです。
/* 1fr(等分割)のカラムが3つ並ぶ */
grid-template-columns: repeat(3, 1fr);
/* → grid-template-columns: 1fr 1fr 1fr; と同じです */
Gridの「入れ子(ネスト)」
Gridでは、グリッドの中にさらにグリッドを入れることができます。
これまでのサンプルからもあるようにFlexboxなど、他のレイアウトも可能です。
複雑なレイアウトを作りたい場合に非常に便利です。
下記のサンプルでもは「親グリッド(セル1)」の中に「子グリッド」をネストしたものになります。
<div class="parent-grid">
<div class="parent-cell">
親グリッド(セル1)
<div class="child-grid">
<div class="child-cell">子グリッドA</div>
<div class="child-cell">子グリッドB</div>
</div>
</div>
<div class="parent-cell">
親グリッド(セル2)
</div>
</div>
.parent-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
max-width: 600px;
}
.parent-cell {
background: #7e57c2;
color: #fff;
text-align: center;
position: relative;
}
.child-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.child-cell {
background: #ec407a;
color: #fff;
}
要素を重ねて表示させる
Grid では同じ領域(同じ線範囲)に複数アイテムを置くと重なって表示されます。
前面・背面はソースコードに記載の順(後ろが前面)か、z-index で制御します。
以下のレイアウトはタイトルの要素が写真に重なって表示されています。これをgridで実装します。

このようなヒーロー(ページの最初に出てくる画像付きのです)のHTMLコードになっています。
<section class="hero">
<img class="hero__img" src="sample.jpg">
<h1 class="hero__title">
<span>CSS Grid Layout</span>
<span>TomiwaTech</span>
</h1>
</section>
gridレイアウト(赤で表示)の中に、gridレイアウト(黄色表示)(ネスト)が書いてあります。
/* 全体の土台(12カラムグリッド) */
.hero{
position: relative;
display: grid;
grid-template-columns: repeat(12, 1fr);
align-items: center;
min-height: 70vh; /* 高さは画面70% */
}
/* 画像は右側に寄せて配置(6列目から右端まで) */
.hero__img{
grid-column: 6 / -1;
grid-row: 1;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 1;
}
/* 見出しは同じ行に重ねて左側に配置 */
.hero__title{
grid-column: 3 / 9;
grid-row: 1;
z-index: 2; /* 画像より前面 */
/* gridレイアウト(内部) */
display: grid;
gap: 16px;
}
/* 背景 */
.hero__title > span{
background: #fff;
padding: .12em .35em;
border-radius: .2em;
box-shadow: 0 8px 30px rgba(0,0,0,.08);
width: fit-content;
}
コードの説明
.heroクラスで12カラムの土台を作っています。
行の指定はしていません。高さは画面70%を確保しています。
.hero{
display: grid;
grid-template-columns: repeat(12, 1fr);
heroの画像(.hero__imgクラス)は右側に寄せて配置しています。
grid-column: 6 / -1 は「6列目の線から右端(-1)まで」となります。-2とすると最後から2番目、-3で最後から3番目という指定ができます。
grid-row: 1; は grid-row: 1 / auto; と同じで、1行目から次の線の直前まで(=1行ぶん) を占有します。
z-index: 1 で重なりのレベルは1となっています。
.hero__img{
grid-column: 6 / -1;
grid-row: 1;
z-index: 1;
見出し(.hero__title)は同じ行に重ねて左側に配置 しています。
grid-column: 3 / 9; は「3列目の線から9番目の線まで」となります。
z-index: 2 で重なりのレベルは2となっていて、画像の1よりも大きく、画像の上にくるようになっています。
さらにgridレイアウトをネストしたgridで2行でgapで行間を入れています。
.hero__title{
grid-column: 3 / 9;
grid-row: 1;
z-index: 2; /* 画像より前面 */
display: grid;
gap: 16px;
}
auto-fit・auto-fill と minmax の活用
より柔軟なレイアウトには、auto-fit や minmax() を組み合わせます。
auto-fit / auto-fill とは?
repeat() の中で auto-fit や auto-fill を使うと、レイアウト幅に応じて、列数を「自動」で調整(カラム数を自動で増減)します。
開発者がレイアウト幅によってカラム数を明示的に指定しなくても、ブラウザが自動で並べてくれる仕組みです。
- auto-fit
→ ウィンドウ幅に合わせて「できるだけ多く」カラムを詰め込むオプションです。
「空きスペースがあればその分カラム数が減る(余白ができる)」 - auto-fill
→ スペースが余っても「空カラム」も作る
(見た目上は auto-fit とほぼ同じになりますが、グリッド要素は増えます)
minmax() とは?
- カラムや行のサイズを「最小値〜最大値」で指定できる関数
- 例:minmax(100px, 1fr)
→ 最小100px、最大は可能な限り広がる(1frまで)
代表的な使い方(レスポンシブ対応させる)
通常、レスポンシブ対応といえばメディアクエリを使って画面幅に応じてカラム数を切り替えます。
例えば、通常は3列表示・798px以下で1列にしたい場合は以下のように書きます。
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
@media (max-width: 798px) {
.container {
grid-template-columns: 1fr;
}
}
gridでは以下のように、repeat()やauto-fit、minmax()と組み合わせて、ブラウザが自動でカラム数を調整してくれるレスポンシブ対応が可能です。
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
- auto-fit
ウィンドウや親要素の幅に応じて自動で列数が増減します。 - minmax(100px, 1fr)
カラム幅は最小100px、最大でスペースいっぱい1frで設定されます。 - repeat(繰返し回数, 1カラムの横幅)
repeat(auto-fit, minmax(100px, 1fr));
最小100pxのカラムが画面幅で表示できるカラム分が表示されます。
例えば、
- 親要素の表示幅が220pxの場合、2カラム(110pxのカラムが2列)になります。
- 表示幅が180pxの場合は、1カラム(180pxのカラムが1列)で表示されます。
- 表示しきれないカラムは次の行に折り返して表示されます。
この仕組みは、レスポンシブなカードレイアウトや画像ギャラリーなど、
ウィンドウサイズに合わせてレイアウトを自動調整したい場面でよく使われます。
少しややこしいですので、実際にどのようにレイアウトが変わるか、グリッドの親幅をスライダーで変えるデモを用意しましたのでこちらでご確認下さい。
CSS Gridジェネレーター の紹介
Web上には便利なCSS Gridジェネレーターが多数公開されています。
マウス操作だけでグリッドを設計し、CSSを自動生成できるので、手軽にレイアウトを試したいときにおすすめです。
生成されるCSSは、本記事で紹介したものと一部異なるプロパティを使っている場合もありますが、
このブログを読んだ方なら、コードの内容も十分理解できるはずです。
ぜひ実際に操作して、どんなCSSが生成されるかを確認してみてください。
CSS Grid Generator
こちらはマウス操作で直感的にGrid Layout が作れるものになっています。
作ったら下にあるCSSの 「Copy CSS」 を押せばすぐにコピーできます。
初めての方にも使いやすいシンプルなツールです。
Layoutit!v2
より複雑なGridを作りたい場合はこちらをおすすめします。
入れ子のレイアウトも作成できるすぐれものです。
UIが洗練されていて、本格的な設計にも対応できます。
最後に
いかがでしょうか?
ここまで1つ1つじっくり読んでいただければ、CSS Grid Layout の概要と基本的な使い方はしっかり掴めたはずです。
Gridのブラウザ対応状況についてですが、IEは非対応ですが、主流のブラウザで問題なく動きますので安心して使って下さい。
また、ご紹介した便利なGridジェネレーターもぜひご自身でも実際に触ってみて、「どのプロパティをどう変えると、レイアウトがどう変わるか」体験しながら学習してみてください。
Gridは慣れてくると複雑なレイアウトもシンプルに書ける強力なツールです。
このブログが、みなさんのコーディングやサイト制作のお役に立てば幸いです。
他にもこんな記事があります。




