CSS Gridの使い方|列・行・配置の基本まとめ
この記事でわかること
- CSS Gridで、ページの骨組みやカード一覧などのレイアウトを組める
- 画面幅が変わっても崩れないレイアウトを作れる
- レイアウトが崩れたときに、原因を見つけて直せる
ブログの骨組みやカード一覧を、思いどおりに並べられずに困ることはありませんか。CSS Gridは、行と列を同時に扱えるレイアウトの仕組みです。少ないコードで、こうしたレイアウトを組めるようになります。
この記事では、実務でよく使う書き方だけに絞って紹介します。
全部を覚えなくても大丈夫だよ!よく使うものから順に見ていこうね
CSS Gridでできることの全体像
やりたいことが決まっている場合は、次の表から使うプロパティと解説を探せます。
| やりたいこと | 使うプロパティ | 解説 |
|---|---|---|
| Gridを使い始める | display: grid |
STEP1 |
| 列の幅を決める | grid-template-columns |
STEP2 |
| アイテムの間を空ける | gap |
STEP2 |
| 画面幅で列数を変える | repeat(auto-fit, minmax()) |
STEP2 |
| アイテムを複数列に広げる | grid-column |
STEP3 |
| ページの骨組みを作る | grid-template-areas |
STEP3 |
| 要素を中央に寄せる | place-items: center |
STEP4 |
| 列のはみ出しを防ぐ | minmax(0, 1fr) |
STEP4 |
前のSTEPで作ったものを次のSTEPで使うため、初めての人はSTEP1から順に読むと迷いません。
マス目を用意する(STEP1)
マス目の大きさを決める(STEP2)
置き場所を決める(STEP3)
見た目を整える(STEP4)
今どのSTEPを読んでいるか意識すると、迷子にならないよ!
STEP1:Gridの土台を作る
display: gridでグリッドコンテナを作る
親要素にdisplay: gridを指定すると、その要素はグリッドコンテナになります。中に入っている子要素はグリッドアイテムと呼ばれます。
HTML
<div class="container">
<div>A</div>
<div>B</div>
</div>
CSS
.container {
display: grid; /* グリッドコンテナになる */
}
注意したいのは、グリッドアイテムになるのは直下の子要素だけという点です。孫要素は通常の並び方のままになります。
<div class="container">
<div>A</div> <!-- グリッドアイテム -->
<div><span>B</span></div> <!-- spanは孫なので対象外 -->
</div>
「孫要素は並ばない」は初心者がよくハマるポイントだよ!
Gridは2017年頃から主要ブラウザで使えるようになりました。現在は安心して使える機能です。詳しい仕様はMDN(グリッドレイアウトの基本概念)で確認できます。
覚えておきたい5つの用語
Gridでは、マス目の各部分に名前が付いています。
| 用語 | 意味 |
|---|---|
| グリッドライン | 行と列を区切る線。番号は1から数える |
| トラック | 行または列1本分 |
| セル | 最小の1マス |
| エリア | 複数のセルをまとめた四角い範囲 |
| ギャップ | トラック同士のすき間 |
エリア(セル2つ分)
トラック(行1本分)
STEP2:列と行のサイズを決める
列の幅と行の高さを決める
列の幅はgrid-template-columns、行の高さはgrid-template-rowsで指定します。スペース区切りで並べた値の数だけ、列や行が作られます。
HTML
<div class="container">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
CSS
.container {
display: grid;
grid-template-columns: 200px 1fr 2fr; /* ① */
grid-template-rows: auto 1fr auto; /* ② */
}
| コード解説 | |
|---|---|
| ① | 列を3本作る(1列目は200px固定、残りを1:2で分ける) |
| ② | 行を3本作る(上下の行は中身の高さ、中央の行は残りの空きを使う) |
fr単位と%の使い分け
frは、残りの空きスペースを比率で分けるGrid専用の単位です。例えば1fr 2frなら、空きを1:2に分けます。
一方、%で指定すると、gapと合わせた合計が100%を超えることがあります。その結果、レイアウトがはみ出しやすくなります。
| 単位 | 向いている場面 |
|---|---|
| px | サイドバーなど、幅を固定したい列 |
| fr | 残りのスペースを柔軟に分けたい列(実務の基本) |
| % | 使う場面は少なめ(gapと併用するとはみ出しやすいため) |
repeat()で同じ指定をまとめる
同じサイズの列を何本も作るときはrepeat()を使います。「何回」「何を」の順に書くだけで、記述を短くできます。
grid-template-columns: repeat(3, 1fr); /* 1fr 1fr 1fr と同じ */
grid-template-columns: repeat(2, 100px 1fr); /* 100px 1fr 100px 1fr と同じ */
例えば3列のカード一覧なら、repeat(3, 1fr)と書くだけで済みます。
minmax()で最小値と最大値を決める
minmax()は、トラックの最小値と最大値を指定する関数です。狭くなりすぎず、広がりすぎない列を作れます。
grid-template-columns: minmax(200px, 300px) 1fr; /* 1列目は200〜300px */
この例では、1列目が200pxから300pxの範囲で伸び縮みします。2列目は残りのスペースを使います。
gapでアイテム同士のすき間を空ける
トラック同士のすき間はgapで指定します。値を1つ書けば行と列の両方に適用されます。2つ書けば「行間→列間」の順に適用されます。
gap: 20px; /* 行・列とも20px */
gap: 20px 10px; /* 行間20px / 列間10px */
gapはトラックとトラックの間にだけ付きます。一番外側には付かないため、端の余白を調整する必要がありません。
アイテムにmarginを付けて間隔を作る方法もあります。ただ現在は、gapを使うのが標準的な書き方です。
画面幅に合わせて列数を自動で変える
ここまでのrepeat()とminmax()を組み合わせると、画面幅に応じて列数が変わるレイアウトを作れます。
auto-fitとminmax()を組み合わせる
カード一覧でよく使うのが次の1行です。メディアクエリを書かなくても、画面幅に応じて列数が自動で変わります。
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* 250px以上の列を入るだけ並べる(auto-fitはそのまま使う) */
「最小250pxの列を、入るだけ並べる」という意味です。広い画面では列が増え、狭い画面では列が減ります。
auto-fillとauto-fitの違い
2つの違いが出るのは、アイテム数が少なく、横幅に余りがあるときです。
| キーワード | 余った空間の扱い | 向いている場面 |
|---|---|---|
auto-fill |
空の列を残す。アイテムは伸びない | 件数が少なくても、カードの幅を揃えたいとき |
auto-fit |
空の列を幅0に潰す。アイテムが横いっぱいに伸びる | アイテムを横幅いっぱいに広げたいとき |
狭い画面ではみ出さない書き方
画面幅が最小値の250pxより狭いと、列が画面からはみ出します。スマホの小さい画面で起こりやすい問題です。
対策として、次の書き方が一般的によく使われています。
grid-template-columns: repeat(
auto-fit,
minmax(min(250px, 100%), 1fr) /* 狭い画面でもはみ出さない */
);
min(250px, 100%)は、250pxと親要素の幅のうち、小さい方を最小値にするという意味です。
カード一覧のこの書き方は、コピーして使い回すと便利だよ!
STEP3:アイテムを好きな位置に配置する
置き場所の指定には、線の番号で指定する方法と、エリアに名前を付けて指定する方法の2つがあります。
線の番号で配置する
アイテムの位置は、グリッドラインの番号で指定できます。grid-column: 1 / 3は「列ライン1から3まで」、つまり2列分を占めるという意味です。
書き方は3通りあります。広げたいアイテムに、どれか1つを指定します。
grid-column: 1 / 3; /* ライン1から3まで(2列分を占める) */
grid-column: span 2; /* 開始位置は自動(2列分を占める) */
grid-column: 1 / -1; /* 端から端まで(最後の線まで占める) */
grid-columnは、開始位置と終了位置をまとめて書けるショートハンド※1です。行方向も、同じようにgrid-rowで指定できます。
-1は「自分で定義したグリッドの最後の線」を指します。自動で追加された行や列には効かないので注意しましょう。
※1:ショートハンド…複数のプロパティを1行でまとめて書ける書き方。ここでは grid-column-start と grid-column-end をまとめています。
grid-template-areasで名前を付けて配置する
grid-template-areasを使うと、レイアウトを文字で図のように描けます。各エリアに名前を付け、アイテム側でgrid-areaを指定して配置します。
HTML
<div class="container">
<div class="header">ヘッダー</div>
<div class="sidebar">サイドバー</div>
<div class="main">メイン</div>
<div class="footer">フッター</div>
</div>
CSS
.container {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas: /* ① */
"header header"
"sidebar main"
"footer footer";
}
.header {
grid-area: header; /* ② */
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
| コード解説 | |
|---|---|
| ① | 1行目は2列ともheader、2行目は左をsidebar・右をmainにする(エリア名は自分で決める) |
| ② | この要素をheaderエリアに配置する(①で付けたエリア名を書く) |
エリア名を書くときの注意点
- 各行の列数を揃える
- エリアは四角形にする(L字などは作れない)
- 空のセルは「.」で表す
スマホでは1カラムに切り替える
メディアクエリの中でareasを書き換えるだけで、スマホ用のレイアウトに切り替えられます。HTMLを変更する必要はありません。
HTML
<div class="container">
<div class="header">ヘッダー</div>
<div class="sidebar">サイドバー</div>
<div class="main">メイン</div>
<div class="footer">フッター</div>
</div>
CSS
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr; /* ① */
grid-template-areas: /* ② */
"header"
"main"
"sidebar"
"footer";
}
}
| コード解説 | |
|---|---|
| ① | 1列だけにする |
| ② | メインの下にサイドバーを並べる |
線の番号とエリア名の使い分け
ブログの骨組みはareasで組むと、あとから見てもわかりやすいよ!
自動で追加される行のサイズを決める
定義した行や列よりアイテムが多いと、ブラウザが自動でトラックを追加します。これを暗黙グリッドと呼びます。
自動で追加される行の高さは、grid-auto-rowsで指定します。列の場合はgrid-auto-columnsを使います。
grid-auto-rows: minmax(150px, auto); /* 最低150px、中身に応じて伸びる */
例えばカード一覧で記事が増えても、追加された行は最低150pxの高さを確保できます。
STEP4:位置を揃えて崩れを防ぐ
揃えるプロパティは3種類
揃えるためのプロパティは、何を動かすかで3種類に分かれます。justifyは横方向、alignは縦方向を担当します。
| プロパティ | 動かす対象 | 指定する場所 |
|---|---|---|
justify-items / align-items |
全アイテムのセル内での位置 | コンテナ |
justify-self / align-self |
特定のアイテムだけの位置 | アイテム |
justify-content / align-content |
グリッド全体の位置(コンテナに余白があるとき) | コンテナ |
それぞれ、place-items・place-self・place-contentというショートハンドで、縦横をまとめて書けます。
上下左右の中央寄せ
よく使うのが、要素を上下左右の中央に置く書き方です。Gridなら2つのプロパティだけで実現できます。
HTML
<div class="container">
<div>中央に配置</div>
</div>
CSS
.container {
display: grid;
place-items: center; /* 上下左右の中央に配置 */
}
1frでレイアウトがはみ出すときの対処法
1frを指定したのに、列がはみ出すことがあります。原因は、1frの最小幅が実質的に「中身の最小幅」になるためです。
特に、長いURLや長い英単語、幅の大きい画像、pre要素が入ると起こりやすくなります。ブログ記事では、コードブロックで発生しやすい問題です。
対策は、コンテナ側とアイテム側の2通りあります。
HTML
<div class="container">
<div class="item">長いURLやコードなど</div>
</div>
CSS
.container {
display: grid;
grid-template-columns: minmax(0, 1fr); /* ① */
}
.item {
min-width: 0; /* ② */
}
| コード解説 | |
|---|---|
| ① | コンテナ側で対策する方法 |
| ② | アイテム側で対策する方法 |
| 方法 | 向いている場面 |
|---|---|
minmax(0, 1fr) |
コンテナ側で、列全体をまとめて対策したいとき |
min-width: 0 |
特定のアイテムだけを対策したいとき |
「なぜかはみ出す」ときは、minmax(0, 1fr)を疑ってみてね!
さいごに
まとめ
CSS Gridは、土台を作る、サイズを決める、配置する、揃えて崩れを防ぐ、の順に組むと迷わずレイアウトを作れます。まずは次の3つを押さえれば、多くの場面に対応できます。
まず押さえたい3つの書き方
- 列の幅は
grid-template-columnsとfrで決める - カード一覧は
repeat(auto-fit, minmax())で列数を自動調整する - ページの骨組みは
grid-template-areasで組む
慣れてきたら、線の番号での配置や揃えのプロパティも組み合わせてみてください。
よくある質問
FlexboxとGridはどう使い分ければいい?
行と列を同時に揃えたいならGrid、1方向に並べるならFlexboxが目安です。
実務では、併用するのが一般的です。ページの骨組みはGridで組み、ナビメニューやボタン群などの内部はFlexboxで並べます。
子要素の中身がグリッドに並びません
グリッドアイテムになるのは、直下の子要素だけです。孫要素も並べたい場合は、その子要素にもdisplay: gridを指定します。
グリッドアイテムの範囲は「display: gridでグリッドコンテナを作る」で解説しています。
grid-column: 1 / -1 で端まで広がりません
-1は、自分で定義したグリッドの最後の線を指します。自動で追加された列には効きません。grid-template-columnsで列を定義しているか確認しましょう。
線の番号の書き方は「線の番号で配置する」で解説しています。
auto-fillとauto-fitはどちらを使えばいい?
アイテムを横いっぱいに広げたいならauto-fitを選びます。件数が少なくてもカードの幅を揃えたいなら、auto-fillを選びます。
2つの違いは「auto-fillとauto-fitの違い」で解説しています。
参考にした公式情報
どのページも英語ですが、ブラウザの翻訳機能を使えば日本語で読めます。

