Back to Blog
CSSGridSubgridLayout

CSS Subgrid Layouts

Master CSS subgrid for nested grid alignment. From card layouts to forms to complex nested structures.

B
Bootspring Team
Engineering
February 9, 2021
5 min read

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; }
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.

Share this article

Help spread the word about Bootspring