複数のカードを3列に並べたいとき、「どの要素に display: grid を書くの?」「grid-template-columns の 1fr は何を表すの?」と迷う方は多いのではないでしょうか。
CSS Gridは、行と列で作る格子を基準に要素を配置するレイアウト方法です。最初からすべてのプロパティを覚える必要はありません。まずは親要素に指定する3つの基本、display: grid・grid-template-columns・gap を押さえると、カード一覧や画像ギャラリーを組めるようになります。
この記事は、HTMLのタグとCSSの基本的な書き方を学び、次にカードの配置を整えたい方に向けた解説です。親要素と子要素の関係から始め、手元のHTMLファイルで3列のカードを作り、狭い画面では1列に切り替えます。うまく並ばない場合も、症状から確認箇所を絞れるように進めていきましょう。
- CSS Gridの仕組みと、グリッドコンテナー・グリッドアイテムの関係
display: gridを親要素に指定する方法grid-template-columns・fr・repeat()で列を作る方法gapで行間・列間を整える方法と、効かないときの確認順
CSS Gridとは
CSS Grid(CSS Grid Layout)は、行と列でできたマス目を作り、そのマス目に沿って要素を並べるCSSのレイアウト方法です。カード一覧、画像ギャラリー、ページ全体の構成など、横方向と縦方向を同時にそろえたい場面に向いています。
CSS Gridは、行と列の二方向を扱うため「二次元レイアウト」と呼ばれます。一方、Flexboxは横一列または縦一列のように、一方向を基準に並べることが得意です。
| 比較する点 | CSS Grid | Flexbox |
|---|---|---|
| 得意な方向 | 行と列の二方向 | 行または列の一方向 |
| 主な考え方 | 先に格子を作って配置する | アイテムを一方向へ並べる |
| 向いている例 | カード一覧、ギャラリー、ページ構成 | メニュー、ボタン列、中央揃え |
どちらか一方だけを使う必要はありません。ページ全体をGridで分け、各エリア内のボタンをFlexboxで並べるように、目的に応じて組み合わせられます。Flexboxを復習したい方は「CSSのFlexboxとは?」も参考にしてください。
親要素と直接の子要素の役割
CSS Gridでは、display: grid を指定した要素を「グリッドコンテナー」、その直接の子要素を「グリッドアイテム」と呼びます。
<div class="grid-box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
この例では、.grid-box が親要素です。3つの .item は .grid-box の直接の子要素なので、Gridの配置対象になります。孫要素まですべてが自動的にグリッドアイテムになるわけではありません。
MDNの「グリッドレイアウトの基本概念」でも、グリッドコンテナーとグリッドアイテム、列や行を構成するトラックなどの基本用語を確認できます。

display: gridでグリッドを有効にする
まずは、先ほどのHTMLに最小限のCSSを加えます。
.grid-box {
display: grid;
}
display: grid は、並べたい子要素ではなく、それらを直接包む親要素に指定します。この宣言により、親要素の内側でGridレイアウトが有効になります。
display: grid だけでは列数を指定していないため、基本の状態では子要素は1列に並びます。3列にしたい場合は、親要素に grid-template-columns も指定します。
display の基本から確認したい場合は、「CSSのdisplayとは?」も参考にしてください。MDNの「display」では、grid が要素の内側をグリッドモデルでレイアウトする値として定義されています。
並べ方とカード装飾の指定先
この記事で扱う display: grid・grid-template-columns・gap は、並べたい要素を包む親要素に書きます。一方、カードの背景色・枠線・カード内の余白は子要素に書きます。親にも背景色や余白を指定できますが、まずは「一覧の並べ方」と「各カードの見た目」を分けると整理しやすくなります。
.grid-box {
display: grid;
}
.item {
padding: 16px;
border: 1px solid #7a8e6d;
border-radius: 8px;
}
「並べ方は親、カードの見た目は子」と役割を分けると、どこに何を書くか判断しやすくなります。
grid-template-columnsで列幅を決める
grid-template-columns は、グリッドの列数と各列の幅を定義するプロパティです。値を空白で区切って並べると、その数だけ列が作られます。
.grid-box {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
この例では、同じ幅の列を3つ作ります。6個のアイテムがあれば、左から右へ3個並び、残りの3個は次の行へ自動配置されます。
| 指定例 | 作られる列 | 向いている場面 |
|---|---|---|
200px 200px | 200pxの2列 | 列幅を固定したい |
200px 1fr | 固定列+残りの幅 | サイドバー+本文 |
repeat(3, 1fr) | 同じ幅の3列 | カード一覧、ギャラリー |
詳しい構文と値は、MDNの「grid-template-columns」で確認できます。
frの意味と最小幅
以下の短いコードは指定の比較例です。試すときは、使いたい grid-template-columns の宣言を1つ選び、親要素のCSSの波かっこの中に書いてください。同じ規則に両方を書くと、後ろの指定が有効になります。
fr は、基本的には親要素の横幅から固定幅や gap を差し引いた「残りの幅」を分ける単位です。1fr 1fr 1fr なら、残りの幅を3つに分けます。
/* 同じ幅の3列 */
grid-template-columns: 1fr 1fr 1fr;
/* 利用できる空間を1対2で分ける2列 */
grid-template-columns: 1fr 2fr;
1fr 2fr は、利用できる残りの幅を1対2で分けます。ただし、1fr には内容に応じた最小幅があるため、改行できない長い文字列や大きな画像によって列が広がる場合があります。「必ず等幅になる」「はみ出しがすべて直る」という指定ではありません。固定幅と組み合わせて 240px 1fr のようにも書けます。
33.33% 33.33% 33.33% のようにパーセントで3列を作ると、列幅だけで親要素のほぼ100%を使います。そこへ2か所分の gap が加わるため、親要素からはみ出すことがあります。fr を使うと、固定幅や gap を差し引いた後の空間を分けやすくなります。
repeat()で同じ指定を短く書く
同じ列幅を繰り返すときは、repeat() 関数を使えます。
/* 次の2つは同じ3列を作る */
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
repeat(3, 1fr) の最初の値は繰り返す回数、2つ目の値は繰り返す列幅です。列数を変えるときは、最初の数値だけを変更できます。

gapでアイテム間の余白を作る
gap は、グリッドの行と列の間にすき間を作るプロパティです。
.grid-box {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
gap: 24px と1つだけ指定すると、行間と列間の両方が24pxになります。先ほどの3枚・3列の例は1行しかないため、見えるのは列間だけです。4枚目を追加して2行になると、行間も確認できます。
行間と列間を変えたい場合は、値を2つ書きます。
.grid-box {
gap: 16px 24px;
}
2つの値は、最初が行間、2つ目が列間です。この例では、上下のすき間が16px、左右のすき間が24pxになります。MDNの「gap」では、gap が row-gap と column-gap の一括指定であることも確認できます。
gap・padding・marginの違い
gap はグリッドアイテム同士の間だけに作用し、コンテナーの外周には余白を作りません。コンテナーの内側全体に余白が必要なら padding、コンテナーの外側を離したいなら margin を使います。
gap:グリッドアイテム同士の間隔padding:コンテナーの境界と内側の内容との間隔margin:要素の境界より外側の間隔

各カードに margin を付けると、カード一覧の外周にも余白ができ、端のカードだけ margin を消す調整が必要になる場合があります。gap なら、カード同士の間だけに余白を付けられます。余白を含む箱の大きさに迷った場合は、「CSSのボックスモデルとは?」も参考にしてください。
3列カードを作る手順
ここまでの3つの基本を組み合わせて、3枚のカードを横に並べます。この実践例では、親のクラス名を card-grid、子のクラス名を card にします。
新しいフォルダーに index.html と style.css を作ります。次のHTMLを index.html に、その下のCSSを style.css に保存してください。link が同じフォルダーのCSSを読み込みます。viewport の指定は、スマートフォンでも画面幅に合わせて表示するために入れています。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Gridの練習</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="card-grid">
<article class="card">
<h3>HTML</h3>
<p>ページの構造を作ります。</p>
</article>
<article class="card">
<h3>CSS</h3>
<p>見た目とレイアウトを整えます。</p>
</article>
<article class="card">
<h3>JavaScript</h3>
<p>ページに動きを加えます。</p>
</article>
</div>
</body>
</html>
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.card {
padding: 24px;
background-color: #f5f6f2;
border: 1px solid #7a8e6d;
border-radius: 12px;
}
.card h3 {
margin-top: 0;
}
.card-grid がグリッドコンテナーで、直接の子である3つの .card がグリッドアイテムです。repeat(3, 1fr) で同じ幅の3列を作り、gap: 24px でカード同士の間隔を付けています。
両方を保存し、index.html をブラウザーで開きます。HTML・CSS・JavaScriptの3枚に枠線と背景色が付き、横に並んでいれば成功です。この段階では、表示領域を狭めても列数は3列のままです。ファイル名が style.css.txt になっていないことも確認してください。
3列のまま表示領域を狭くすると、カード内の文章が読みにくくなることがあります。メディアクエリとは、表示領域の幅などの条件に応じてCSSを切り替える書き方です。次のコードを style.css の末尾へ追加し、保存してください。既存の .card-grid の波かっこの内側へ入れず、閉じかっこの後に置きます。
@media (max-width: 700px) {
.card-grid {
grid-template-columns: 1fr;
}
}
この指定は、ブラウザーの表示領域が700px以下なら1列に切り替えます。端末の種類で判定する指定ではないため、PCでも表示領域を狭めると1列になります。700pxはこの練習用の値です。条件の意味は、MDNの「widthメディア特性」で確認できます。
index.html を再読み込みし、ブラウザーの表示領域を広げたり狭めたりします。700pxより広いと横3列、700px以下では縦1列になり、再び広げると3列に戻れば完了です。次の図で完成状態を確認してください。表示が合っていれば、この後の「効かないときの確認」は飛ばして構いません。
間隔も試したい場合は、gap: 24px を gap: 40px へ変更して保存・再読み込みします。カード同士の間が広がることを確かめたら、24pxへ戻してください。実際のページでは、3列の文章が窮屈になり始める幅を切り替えの目安にします。

CSS Gridが効かないときの確認順
まずは保存と再読み込みを済ませてから、当てはまる症状を確認してください。CSSの値は一度に一つずつ変えると、何が原因だったか分かりやすくなります。
枠線や背景色も変わらない
index.html と style.css が同じフォルダーにあるか、href="style.css" のつづりが一致するかを確認します。次に、HTMLの class="card-grid" とCSSの .card-grid、class="card" と .card が対応しているかを見ます。カードの枠線と背景色が出れば、CSSが読み込まれていると判断できます。
枠線は出るが横に並ばない
メディアクエリを追加済みで、表示領域の幅が700px以下なら、1列は今回のコードどおりの表示です。広い画面でも1列なら、3枚を直接包む .card-grid に display: grid と grid-template-columns: repeat(3, 1fr) があるか確認します。子の .card に書いても、兄弟のカードは並びません。別の要素で包んだ場合は、直接の子が何かをHTMLで見直してください。
間隔が付かない・外周だけ詰まる
gap は親に書き、gap: 24px; のように、0以外の長さには単位を付けます。gap: 24; は無効になり、その宣言は適用されません。余白をなくす gap: 0; では単位を省略できます。1行しかない場合は行間が見えないため、4枚目を追加して確認できます。外周だけを空けたい場合は gap を増やさず、親の padding を調整してください。
カードが親の幅からはみ出す
固定幅の列と列間の合計が、親の内容を置ける幅(paddingとborderを除いた幅)を超えていないか確認します。たとえば 200px 200px 200px と gap: 24px には、合計648pxが必要です。可変幅にしたい場合は repeat(3, 1fr) が候補になります。
それでもはみ出す場合は、カードに指定した固定幅、折り返せない長い文字列、大きな画像を確認します。fr にも内容による最小幅があるため、列指定だけでは直らないことがあります。まず原因の内容や幅を直し、親の内側に収まったかを再確認してください。幅の確認方法は「CSSで幅と高さを指定する方法」で解説しています。
Chromeの開発者ツールを使う場合、Styles(スタイル)欄の取り消し線だけで「上書きされた」と判断しないようにしましょう。プロパティ名や値が無効な場合にも取り消し線が表示されます。警告アイコンがあればつづりや単位を確認し、上書きの場合は同じプロパティの別の指定を確認します。表示の読み方は、Chrome公式の「無効・上書きされたCSSの確認」が参考になります。
よくある質問
- 行の高さも指定しないといけませんか?
-
この例では不要です。列数だけを指定すると、必要な行が自動で作られ、内容に応じた高さになります。同じ行のカードは初期設定では行の高さまで伸びますが、別の行まで同じ高さになるとは限りません。まずは高さを固定せず、文章量を変えて確認してください。
- カードの中にもGridを使えますか?
-
使えます。たとえば
.cardにもdisplay: gridを指定すると、そのカード自身は外側のGridのアイテムのまま、カードの直接の子を並べる新しいコンテナーにもなります。外側の列設定がそのまま孫要素へ引き継がれるわけではないため、内側の並べ方は別に指定します。 - 見た目の順番はCSSで入れ替えてもよいですか?
-
Gridでは見た目の位置を変えられますが、HTMLの順番まで変わるわけではありません。読み上げやキーボード操作の順番とずれる場合があるため、今回の基本例では読みたい順にHTMLを書き、そのまま自動配置する方法がおすすめです。
まとめ
CSS Gridは、行と列の二方向を扱えるレイアウト方法です。まずは、親要素に書く3つの基本を覚えましょう。
display: gridでGridレイアウトを有効にするgrid-template-columnsで列数と列幅を決める1frは利用できる空間を分け、repeat()は同じ指定を繰り返すgapで行と列の間隔をまとめて整える- 効かないときは、読み込み・列指定・間隔・はみ出しの症状から確認する
3列と1列が条件どおりに切り替わり、カード同士の間隔も確認できれば、この練習は完了です。列を作る指定と間隔を作る指定を分けて考えると、別のカード一覧にも応用できます。
目的別に次の記事を選ぶ
基本の配置ができたら、次に知りたい内容に合わせて読み進めてください。
画面幅に合わせた切り替えを詳しく知りたい方は、メディアクエリの条件と max-width・min-width の使い分けを確認してください。

3列には並ぶのに長い文字列や画像がはみ出す方は、列の最小幅と中身の折り返しを分けて直す方法を確認してください。


