CSS Grid パターン
問題
CSS Gridは最も強力なCSSレイアウトシステムですが、AIエージェントはしばしば活用しきれなかったり、誤った使い方をしたりします。よくあるミスとしては、auto-fill と auto-fit の混同、レスポンシブパターンではなく固定のカラム数を使う、可読性が大幅に向上するのに grid-template-areas を避ける、minmax() がネイティブでレスポンシブに対応できるのにJavaScriptやメディアクエリに頼る、などがあります。
解決方法
CSS Gridは二次元のレイアウトシステムです。ページレベルのレイアウト、レスポンシブなカードグリッド、行と列の両方でアイテムを揃える必要があるあらゆるシナリオに使いましょう。auto-fill/auto-fit と minmax() の組み合わせにより、メディアクエリを1つも使わずにレスポンシブレイアウトが実現できます。
コード例
auto-fill vs auto-fit
アイテムの数がグリッドに収まる数より少ない場合に、違いが現れます。
/* auto-fill: keeps empty tracks, preserving the grid structure */
.grid-fill {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
/* auto-fit: collapses empty tracks, items stretch to fill space */
.grid-fit {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
5カラム分の幅があるコンテナに3つのアイテムがある場合:
auto-fillは5カラムを作り、2つは空のまま残します。アイテムは約200pxの幅を維持します。auto-fitは2つの空カラムを折りたたみます。アイテムはコンテナの全幅に広がります。
auto-fit を使う場面: カードグリッド、ギャラリーレイアウトなど、アイテムが利用可能なスペースを埋めるべきほとんどのUIパターン。
auto-fill を使う場面: アイテム数に関係なくカラム幅を一定に保ちたい場合(フォームフィールドやデータ入力レイアウトなど)。
レスポンシブなカードグリッド(メディアクエリ不要)
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 1.5rem;
}
<div class="card-grid">
<article class="card">Card 1</article>
<article class="card">Card 2</article>
<article class="card">Card 3</article>
<article class="card">Card 4</article>
</div>
名前付きグリッドエリア
グリッドエリアは複雑なレイアウトを読みやすく保守しやすくします。
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Responsive: stack on narrow viewports */
@media (max-width: 768px) {
.page-layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
<div class="page-layout">
<header class="header">Header</header>
<aside class="sidebar">Sidebar</aside>
<main class="main">Main Content</main>
<footer class="footer">Footer</footer>
</div>
grid-template ショートハンドによる複雑なレイアウト
grid-template ショートハンドは grid-template-rows、grid-template-columns、grid-template-areas を1つの宣言にまとめます。
.dashboard {
display: grid;
grid-template:
"nav nav nav" 60px
"side main aside" 1fr
"footer footer footer" 80px
/ 200px 1fr 250px;
min-height: 100vh;
gap: 1rem;
}
複数の行や列にまたがる
.featured-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 1rem;
}
.featured-item {
grid-column: span 2;
grid-row: span 2;
}
Dense パッキング(隙間の埋め合わせ)
.masonry-like {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-auto-flow: dense;
gap: 1rem;
}
dense キーワードは、DOMの後方にある小さなアイテムで空のセルを埋めるようブラウザに指示し、より詰まったレイアウトを作ります。
AIがよくやるミス
auto-fitを意図しているのにauto-fillを使う。 ほとんどのUIパターンでは、アイテムが利用可能なスペースを埋めるように広がることを望みます(auto-fit)。AIエージェントは空のトラックを残すauto-fillを選びがちです。min()ガードなしでminmax(300px, 1fr)を書く。 300px未満のビューポートで水平オーバーフローが発生します。常にminmax(min(100%, 300px), 1fr)を使いましょう。grid-template-areasを避ける。 AIエージェントは行/列番号で配置しがちで、読みにくいコードになります。名前付きエリアは自己ドキュメンティングで、リファクタリングも容易です。repeat(auto-fit, ...)の代わりに明示的なカラム数を設定する。 固定のgrid-template-columns: repeat(3, 1fr)はレスポンシブにするためにメディアクエリが必要です。auto-fitとminmax()なら自動的に対応できます。- カードのグリッドにflexboxを使う。 カードが行と列の両方で一貫したサイズで揃う必要がある場合、CSS Gridが正しいツールです。
gapを忘れてグリッドアイテムにmarginを使う。 Gridにはgapサポートが組み込まれています。グリッドアイテムのmarginはグリッドトラックの外側にスペースを追加し、整列を崩します。- フルページのグリッドレイアウトに
min-height: 100vhを設定しない。 これがないと、グリッドはコンテンツの高さしか取らず、フッターなどのエリアが下端に届きません。
使い分け
CSS Grid が適しているケース
- 二次元レイアウト(行と列を同時に扱う)
- header、sidebar、main、footerを持つページレベルのレイアウト
- auto-fit/auto-fill を使ったレスポンシブなカードグリッド
- 複数の行や列にまたがるアイテムを含むレイアウト
- 名前付きエリアによる可読性が有益なレイアウト
代わりにFlexboxを使うべき場合
- 一次元のレイアウトのみ必要な場合(単一の行または列)
- アイテムの幅が不明で、スペースを分配する必要がある場合(ナビゲーション、ツールバー)
- アイテムを折り返したいが、行間でのカラム整列は不要な場合
Tailwind CSS
Tailwindはレスポンシブブレークポイントプレフィックス付きのグリッドユーティリティを提供しています。CSS Gridの auto-fit/auto-fill と minmax() はユーティリティとして提供されていませんが、Tailwindのレスポンシブプレフィックス(sm:、md:、lg:)が明示的なブレークポイントベースの代替手段を提供します。