CSS Gridでカード一覧を崩さず並べる基本設計
CSS Gridを使うと、商品一覧、記事カード、管理画面のパネルのような「同じ形の箱を並べるレイアウト」を、少ないCSSで整えられます。
特に実務で便利なのは、画面幅に合わせてカードの列数を自動で変えられることです。PCでは3列、タブレットでは2列、スマホでは1列、という調整を毎回細かく書かなくても、repeat()、minmax()、auto-fitを組み合わせると自然に収まります。
この記事で分かることは次の通りです。
- CSS Gridでカード型レイアウトを作る基本形
grid-template-columns、gap、minmax()の考え方- 入力するHTMLと、期待できる表示結果
- カードが詰まりすぎる、横にはみ出す、余白が揃わないときの直し方
- GridとFlexboxの使い分け
対象は、HTML/CSSの基本を書いたことがあり、WordPressの一覧パーツやWebサイトのカードUIを整えたい人です。CSS Gridは主要ブラウザで広く使えるレイアウト機能ですが、細かな互換性は実案件の対象ブラウザに合わせて確認してください。
前提環境とCSS Gridの役割
CSS Gridは、縦と横の両方向をまとめて管理するレイアウト機能です。
カード型レイアウトでは、親要素に「ここをグリッドにする」と指定し、子要素をカードとして並べます。横方向の列幅、行間、列間を親側で決められるため、カードごとに余白を個別指定するより管理しやすくなります。
今回の例は、次の前提で書きます。
- HTML: 通常の
divとarticleで構成 - CSS: CSS Grid Layoutを使用
- 想定用途: 記事一覧、商品一覧、サービス紹介、管理画面のカード一覧
- 対象ブラウザ: 現行の主要ブラウザを想定
CSS Gridの基本概念は、MDNのBasic concepts of grid layoutでも整理されています。実務では、概念をすべて暗記するより、まず「親にGridを指定し、列の作り方を決める」と覚えるほうが使い始めやすいです。
ここがポイント: カード型レイアウトでは、カード自身ではなく、カードを包む親要素にGridのルールを書くのが基本です。
まずは3列のカード一覧を作る
最小構成では、親要素にdisplay: gridを指定し、grid-template-columnsで列数を決めます。
入力例: HTML
<section class="card-list">
<article class="card">
<h2>記事タイトルA</h2>
<p>概要文が入ります。カードごとに短い説明を置きます。</p>
</article>
<article class="card">
<h2>記事タイトルB</h2>
<p>同じ形の要素を並べると、一覧として読みやすくなります。</p>
</article>
<article class="card">
<h2>記事タイトルC</h2>
<p>商品、サービス、投稿一覧などで使える形です。</p>
</article>
</section>
入力例: CSS
.card-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
background: #fff;
}
.card h2 {
margin: 0 0 12px;
font-size: 1.1rem;
}
.card p {
margin: 0;
line-height: 1.7;
}
出力イメージ
このCSSでは、.card-listの中にあるカードが横3列で並びます。
display: grid: 親要素をGridコンテナにするgrid-template-columns: repeat(3, 1fr): 同じ幅の列を3つ作るgap: 24px: カード同士の余白をまとめて指定する
1frは、使える幅を分け合う単位です。repeat(3, 1fr)なら、横幅を3等分して3列を作ります。
この書き方は分かりやすい一方で、スマホ表示では列が狭くなりすぎます。実務では、次のレスポンシブな書き方までセットで覚えるほうが安全です。
実務ではauto-fitとminmaxで列数を自動調整する
カード型レイアウトでは、固定の3列よりも「カードの最小幅を守りながら、入るだけ並べる」指定が使いやすいです。
次のCSSにすると、画面幅が広いときは複数列、狭いときは自然に1列へ変わります。
.card-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
この1行がカード一覧の中心です。
それぞれの意味
repeat(auto-fit, minmax(240px, 1fr))は長く見えますが、分けると理解しやすくなります。
repeat(...): 同じ列の指定を繰り返すauto-fit: 入るだけ列を作るminmax(240px, 1fr): 列幅は最低240px、余裕があれば広がる
つまり、カードの最小幅を240pxに保ち、残りの幅は均等に分けるという指定です。
スマホ幅で240pxのカードが2列入らなければ1列になります。PC幅で3列や4列入るなら、自然に列が増えます。メディアクエリを書かずに済む場面も多く、WordPressの記事一覧ブロックやカスタムHTMLでも扱いやすい書き方です。
240pxは固定の正解ではない
240pxは例です。実際には、カードの中身に合わせて調整します。
- タイトルと短い説明だけ: 220pxから260px程度
- 画像、タイトル、抜粋があるカード: 280pxから340px程度
- 管理画面の小さなステータスカード: 180pxから240px程度
重要なのは、列数を先に決めることではありません。カードの中身が読める最小幅を先に決めることです。
カードの高さと余白を揃える書き方
カード一覧では、列数よりも「見た目の揃い方」でつまずくことがあります。
タイトルの長さや本文量が違うと、カードの高さがばらつきます。高さが違うこと自体は問題ではありませんが、ボタンやリンクを下に揃えたい場合は、カード内部にも少し工夫が必要です。
ボタン位置を下に揃える例
<section class="card-list">
<article class="card">
<h2>CSS Gridの基本</h2>
<p>カード型レイアウトを作るための最小構成を説明します。</p>
<a class="card-link" href="#">続きを読む</a>
</article>
<article class="card">
<h2>長いタイトルが入るカードの例</h2>
<p>タイトルや説明文の長さが違っても、リンク位置を揃えたい場面があります。</p>
<a class="card-link" href="#">続きを読む</a>
</article>
</section>
.card {
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
background: #fff;
}
.card-link {
margin-top: auto;
display: inline-block;
padding-top: 16px;
}
ここでは、外側の一覧にはCSS Grid、カード内部の縦並びにはFlexboxを使っています。
GridとFlexboxは競合するものではありません。外側の「面」をGridで作り、カード内の「縦方向の配置」をFlexboxで整えると、役割がはっきりします。
よくある失敗と直し方
CSS Gridは便利ですが、指定の意味を取り違えると表示が崩れます。特に初心者がつまずきやすいのは、横幅、余白、子要素の扱いです。
カードが横にはみ出す
原因になりやすいのは、カードや画像に固定幅を入れているケースです。
.card {
width: 320px;
}
Gridの列幅は親が決めるため、カード側に固定幅を入れると、画面幅によっては列からはみ出します。基本はカードを列幅に任せます。
.card {
width: auto;
}
.card img {
max-width: 100%;
height: auto;
}
画像入りカードでは、imgにmax-width: 100%を指定しておくと、画像だけがカードから飛び出す失敗を防ぎやすくなります。
gapではなくmarginで余白を作っている
カード同士の余白は、できるだけ親要素のgapで指定します。
.card-list {
display: grid;
gap: 24px;
}
子要素ごとにmarginを付けると、端だけ余白が増えたり、行の折り返し後に意図しない隙間が出たりします。一覧全体の余白は親、カード内部の余白は子、という分担にすると管理しやすくなります。
auto-fillとauto-fitの違いで迷う
auto-fillとauto-fitは似ています。どちらも入るだけ列を作る指定ですが、余った列の扱いが異なります。
初心者がカード一覧でまず使うなら、auto-fitからで十分です。空の列が残りにくく、カードが自然に広がるため、一般的な一覧UIでは扱いやすいからです。
必要になったら、MDNのrepeat()やminmax()の説明を確認し、意図した列の残り方になるかを検証するとよいでしょう。
GridとFlexboxはどう使い分けるか
カード一覧の外枠にはGrid、1行の整列やカード内の配置にはFlexboxが向いています。
ざっくり分けると、次のようになります。
| 使いたい場面 | 向いている方法 | 理由 |
|---|---|---|
| 記事カードを複数列で並べる | CSS Grid | 列幅と行間を親要素でまとめて管理しやすい |
| ナビゲーションを横並びにする | Flexbox | 1方向の整列や中央寄せが書きやすい |
| カード内のボタンを下に揃える | Flexbox | 縦方向の余白調整に使いやすい |
| ダッシュボードのパネルを格子状に置く | CSS Grid | 縦横の配置を同時に考えやすい |
「GridかFlexboxか」を一つに決める必要はありません。実務では、外側の大きな配置をGridで作り、内側の細かい整列にFlexboxを使う組み合わせがよく合います。
WordPressで使うときの確認ポイント
WordPressでCSS Gridを使う場合は、CSSそのものより、テーマやブロック側の既存スタイルとの重なりに注意します。
特に確認したいのは次の点です。
- テーマ側で
.cardや.gridのような汎用クラスが既に使われていないか - ブロックエディターが自動で付ける余白と二重になっていないか
- 投稿一覧の画像サイズがカード幅に対して大きすぎないか
- スマホ表示で最小幅が大きすぎて横スクロールしていないか
クラス名は、できるだけ用途が分かる名前にします。たとえば、.card-listよりも、記事一覧なら.post-card-list、商品一覧なら.product-card-listのようにすると、テーマCSSとの衝突を減らせます。
最低限のチェックリスト
公開前には、次の4点を見るだけでも崩れを見つけやすくなります。
- 320px前後のスマホ幅で横スクロールが出ない
- タイトルが2行以上になってもカード内の余白が破綻しない
- 画像がカード幅からはみ出さない
- カードが1件、2件、5件など半端な件数でも不自然に見えない
CSS Gridはカード数が変わる一覧に強い一方、コンテンツの長さまでは自動で整えてくれません。タイトル、画像、ボタン位置は、実際の投稿データに近い内容で確認するのが大切です。
まとめ: 列数ではなく最小幅から考える
カード型レイアウトをCSS Gridで作るときは、「3列にしたい」から始めるより、「カードは最低何pxあれば読めるか」から考えると崩れにくくなります。
実務でまず覚える形はこれです。
.card-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
この指定を土台にして、カードの中身に合わせて240pxとgapを調整します。
次に見るべきポイントは、実際のコンテンツです。タイトルが長い投稿、画像サイズが違う商品、ボタンの有無が混ざる一覧で確認すると、Gridの指定だけでは足りない部分が見えてきます。そこをカード内部のCSSで整えれば、スマホでもPCでも読みやすい一覧に近づきます。
