サブグリッド
問題
CSS Gridは直接の子要素のレイアウトに優れていますが、ネストされた要素は親グリッドのトラックサイジングに参加できません。これにより、兄弟コンポーネント間でコンテンツを揃えることが不可能になります — 例えば、カードの行全体でタイトル、説明、ボタンがすべて同じ垂直位置に揃うようにすることができません。AIエージェントがsubgridを使うことはほとんどなく、代わりに固定の高さ、JavaScriptベースの揃え、または動的コンテンツで壊れる複雑な回避策に頼ります。
解決方法
grid-template-columnsやgrid-template-rowsのsubgrid値を使うと、ネストされたグリッドが親のトラック定義を継承できます。子グリッドは親のトラックサイジングに参加するため、兄弟グリッドアイテム間のコンテンツが固定の寸法やトラック定義の重複なしに自然に揃います。
コード例
揃えられたコンテンツのカードレイアウト
最も一般的なsubgridのユースケース:カード間で見出し、コンテンツ、フッターが揃うようにします。
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
.card {
display: grid;
/* Inherit parent's row tracks for this card's internal layout */
grid-row: span 3;
grid-template-rows: subgrid;
gap: 0.75rem;
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 1.5rem;
}
.card h2 {
/* Row 1: title — aligns across all cards */
align-self: start;
}
.card p {
/* Row 2: description — aligns across all cards */
align-self: start;
}
.card .action {
/* Row 3: button — pushed to bottom, aligned across all cards */
align-self: end;
}
<div class="card-grid">
<article class="card">
<h2>Short Title</h2>
<p>Brief description.</p>
<a class="action" href="#">Read more</a>
</article>
<article class="card">
<h2>A Much Longer Card Title That Wraps</h2>
<p>This card has a longer title, but the description and button still align with the other cards.</p>
<a class="action" href="#">Read more</a>
</article>
<article class="card">
<h2>Medium Title</h2>
<p>Another card with varying content length.</p>
<a class="action" href="#">Read more</a>
</article>
</div>
カラム用のSubgrid
ネストされたフォームのラベルと入力フィールドを親グリッドのカラムに揃えます。
.form-grid {
display: grid;
grid-template-columns: 120px 1fr;
gap: 1rem;
}
.field-group {
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
align-items: center;
}
.field-group label {
grid-column: 1;
}
.field-group input {
grid-column: 2;
}
<form class="form-grid">
<div class="field-group">
<label for="name">Name</label>
<input id="name" type="text" />
</div>
<div class="field-group">
<label for="email">Email</label>
<input id="email" type="email" />
</div>
<div class="field-group">
<label for="phone">Phone</label>
<input id="phone" type="tel" />
</div>
</form>
2次元のSubgrid
親グリッドから行とカラムの両方を継承します。
.dashboard {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
.widget {
display: grid;
grid-column: span 1;
grid-row: span 3;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
}
.widget header {
/* Aligns with other widgets' headers */
font-weight: bold;
border-bottom: 1px solid #e5e7eb;
padding-bottom: 0.5rem;
}
.widget footer {
/* Aligns with other widgets' footers */
font-size: 0.875rem;
color: #6b7280;
}
名前付きラインを持つSubgrid
親グリッドの名前付きラインはsubgridに引き継がれます。
.page-layout {
display: grid;
grid-template-columns:
[full-start] 1fr
[content-start] minmax(0, 65ch)
[content-end] 1fr
[full-end];
}
.article {
display: grid;
grid-column: full-start / full-end;
grid-template-columns: subgrid;
}
.article p {
grid-column: content-start / content-end;
}
.article .wide-image {
grid-column: full-start / full-end;
}
gapを重複させないSubgrid
subgridはデフォルトで親のgapを継承します。必要に応じてオーバーライドできます。
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 2rem;
}
.child {
display: grid;
grid-column: span 2;
grid-template-columns: subgrid;
/* Subgrid inherits parent's 2rem gap */
/* Override if needed: */
gap: 0.5rem;
}
ブラウザサポート
- Chrome 117+
- Edge 117+
- Safari 16+
- Firefox 71+
グローバルサポートは97%を超えています。Firefoxが2019年12月に最初にsubgridをリリースしました。Safariが2022年9月に続き、Chrome/Edgeが2023年9月にサポートを追加しました。Subgridはプロダクション利用に安全です。
AIがよくやるミス
subgridをまったく使わない — ほとんどのAIエージェントは、揃えのためにトラック定義を重複させたり固定の高さを使ったりするグリッドレイアウトを生成する- 子グリッドで
subgridを使う代わりにgrid-template-columnsの値を重複させる - 兄弟グリッドアイテム間のコンテンツ揃えにJavaScriptや固定の寸法を使用する
- subgridを適用する前に、子グリッドアイテムを正しい数の親トラックにまたがらせない
- subgridが親の
gap値を継承すること(オーバーライド可能)を忘れる - 子要素に最初に
display: gridを設定せずにsubgridを適用する - ラベルと入力フィールドに一貫した揃えが必要なフォームレイアウトでsubgridを活用しない
使い分け
- カード間でタイトル、コンテンツ、アクションを揃える必要があるカードグリッド
- ラベルと入力フィールドが共有カラムトラックに揃うフォームレイアウト
- 共通のヘッダー/コンテンツ/フッター構造を共有するダッシュボードウィジェット
- ネストされた要素が親グリッドの名前付きラインを参照する必要があるフルブリードコンテンツレイアウト
- ネストされた要素が親グリッドのトラックサイジングに参加する必要があるあらゆるレイアウト
ライブプレビュー
Subgrid — 揃えられたカードコンテンツ