Subgrid lets nested grids inherit track sizing from parents. Here's how to use it effectively.
Basic Subgrid#
1/* Parent grid */
2.grid {
3 display: grid;
4 grid-template-columns: repeat(3, 1fr);
5 gap: 1rem;
6}
7
8/* Child inherits parent tracks */
9.card {
10 display: grid;
11 grid-column: span 3;
12 grid-template-columns: subgrid;
13}
14
15/* Card content aligns with parent grid */
16.card-image { grid-column: 1; }
17.card-content { grid-column: 2; }
18.card-actions { grid-column: 3; }Card Grid Alignment#
1/* Cards with aligned content */
2.card-grid {
3 display: grid;
4 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
5 gap: 2rem;
6}
7
8.card {
9 display: grid;
10 grid-template-rows: auto 1fr auto;
11 gap: 1rem;
12}
13
14/* With subgrid for row alignment */
15.card-grid-aligned {
16 display: grid;
17 grid-template-columns: repeat(3, 1fr);
18 grid-template-rows: repeat(3, auto 1fr auto);
19 gap: 1rem 2rem;
20}
21
22.card {
23 display: grid;
24 grid-row: span 3;
25 grid-template-rows: subgrid;
26}
27
28.card-header { /* Aligns across all cards */ }
29.card-body { /* Stretches to fill */ }
30.card-footer { /* Aligns at bottom */ }Form Layout#
1/* Form with aligned labels and inputs */
2.form {
3 display: grid;
4 grid-template-columns: auto 1fr auto;
5 gap: 1rem;
6}
7
8.form-group {
9 display: grid;
10 grid-column: span 3;
11 grid-template-columns: subgrid;
12 align-items: center;
13}
14
15.form-label {
16 grid-column: 1;
17 text-align: right;
18}
19
20.form-input {
21 grid-column: 2;
22}
23
24.form-hint {
25 grid-column: 3;
26 font-size: 0.875rem;
27 color: #666;
28}
29
30/* All labels align, all inputs align */Nested Navigation#
1/* Main navigation with subgrid */
2.nav {
3 display: grid;
4 grid-template-columns: repeat(4, 1fr);
5}
6
7.nav-item {
8 display: grid;
9 grid-template-columns: subgrid;
10}
11
12.dropdown {
13 display: grid;
14 grid-column: span 4;
15 grid-template-columns: subgrid;
16}
17
18.dropdown-item {
19 /* Aligns with main nav columns */
20}Both Axes Subgrid#
1/* Subgrid on rows and columns */
2.parent {
3 display: grid;
4 grid-template-columns: repeat(4, 1fr);
5 grid-template-rows: auto 1fr auto;
6 gap: 1rem;
7}
8
9.child {
10 grid-column: span 4;
11 grid-row: span 3;
12
13 display: grid;
14 grid-template-columns: subgrid;
15 grid-template-rows: subgrid;
16}
17
18/* Perfect alignment in both directions */Table-Like Layout#
1/* Grid table with subgrid rows */
2.table {
3 display: grid;
4 grid-template-columns: auto 1fr 100px 100px;
5}
6
7.table-row {
8 display: grid;
9 grid-column: span 4;
10 grid-template-columns: subgrid;
11 padding: 0.5rem 0;
12 border-bottom: 1px solid #eee;
13}
14
15.table-row:hover {
16 background: #f5f5f5;
17}
18
19.cell-id { grid-column: 1; }
20.cell-name { grid-column: 2; }
21.cell-status { grid-column: 3; }
22.cell-actions { grid-column: 4; }Gallery with Captions#
1/* Gallery with aligned captions */
2.gallery {
3 display: grid;
4 grid-template-columns: repeat(3, 1fr);
5 grid-auto-rows: 200px auto;
6 gap: 1rem;
7}
8
9.gallery-item {
10 display: grid;
11 grid-row: span 2;
12 grid-template-rows: subgrid;
13}
14
15.gallery-image {
16 grid-row: 1;
17 object-fit: cover;
18 width: 100%;
19 height: 100%;
20}
21
22.gallery-caption {
23 grid-row: 2;
24 padding: 0.5rem;
25 /* All captions align regardless of image height */
26}Responsive Subgrid#
1/* Responsive card layout */
2.cards {
3 display: grid;
4 grid-template-columns: 1fr;
5 gap: 2rem;
6}
7
8@media (min-width: 768px) {
9 .cards {
10 grid-template-columns: repeat(2, 1fr);
11 grid-template-rows: repeat(auto-fill, auto 1fr auto);
12 }
13
14 .card {
15 display: grid;
16 grid-row: span 3;
17 grid-template-rows: subgrid;
18 }
19}
20
21@media (min-width: 1024px) {
22 .cards {
23 grid-template-columns: repeat(3, 1fr);
24 }
25}Timeline Layout#
1/* Timeline with aligned dates and content */
2.timeline {
3 display: grid;
4 grid-template-columns: 100px 20px 1fr;
5 gap: 0 1rem;
6}
7
8.timeline-item {
9 display: grid;
10 grid-column: span 3;
11 grid-template-columns: subgrid;
12 padding: 1rem 0;
13}
14
15.timeline-date {
16 grid-column: 1;
17 text-align: right;
18}
19
20.timeline-marker {
21 grid-column: 2;
22 justify-self: center;
23}
24
25.timeline-content {
26 grid-column: 3;
27}Pricing Table#
1/* Pricing comparison with subgrid */
2.pricing {
3 display: grid;
4 grid-template-columns: repeat(3, 1fr);
5 grid-template-rows: auto auto repeat(5, auto) auto;
6 gap: 0;
7}
8
9.pricing-plan {
10 display: grid;
11 grid-row: span 8;
12 grid-template-rows: subgrid;
13 border: 1px solid #ddd;
14 padding: 1rem;
15}
16
17.pricing-header { grid-row: 1; }
18.pricing-price { grid-row: 2; }
19.pricing-feature-1 { grid-row: 3; }
20.pricing-feature-2 { grid-row: 4; }
21.pricing-feature-3 { grid-row: 5; }
22.pricing-feature-4 { grid-row: 6; }
23.pricing-feature-5 { grid-row: 7; }
24.pricing-cta { grid-row: 8; }
25
26/* Features align across all plans */Fallback for No Support#
1/* Feature detection */
2@supports not (grid-template-columns: subgrid) {
3 .card {
4 display: flex;
5 flex-direction: column;
6 }
7
8 .card-body {
9 flex: 1;
10 }
11}
12
13@supports (grid-template-columns: subgrid) {
14 .card {
15 display: grid;
16 grid-template-rows: subgrid;
17 }
18}
19
20/* Or use grid without subgrid */
21.card-fallback {
22 display: grid;
23 grid-template-rows: auto 1fr auto;
24}Complex Dashboard#
1/* Dashboard with nested subgrids */
2.dashboard {
3 display: grid;
4 grid-template-columns: 250px repeat(3, 1fr);
5 grid-template-rows: auto 1fr 1fr auto;
6 gap: 1rem;
7 height: 100vh;
8}
9
10.sidebar {
11 grid-column: 1;
12 grid-row: span 4;
13}
14
15.main-content {
16 grid-column: 2 / -1;
17 grid-row: 2 / 4;
18
19 display: grid;
20 grid-template-columns: subgrid;
21 grid-template-rows: subgrid;
22}
23
24.widget {
25 display: grid;
26 grid-template-columns: subgrid;
27 /* Widgets align with main grid */
28}Best Practices#
Usage:
✓ Use for aligned nested content
✓ Apply to direct children only
✓ Combine with auto-rows for flexibility
✓ Test responsive behavior
Patterns:
✓ Card layouts with aligned sections
✓ Form labels and inputs
✓ Tables without table elements
✓ Pricing/feature comparisons
Avoid:
✗ Overusing nested subgrids
✗ Forgetting gap inheritance
✗ Ignoring browser support
✗ Complex subgrid hierarchies
Conclusion#
Subgrid enables nested grid alignment without recalculating track sizes. Use it for cards, forms, tables, and any layout requiring consistent alignment across nested elements. Provide fallbacks for browsers without support.