Back to Blog
CSSSubgridGridLayout

CSS Subgrid Guide

Master CSS subgrid for aligning nested grid items with their parent grid's tracks.

B
Bootspring Team
Engineering
February 20, 2019
5 min read

Subgrid allows nested grids to inherit track sizing from their parent grid. Here's how to use it for perfectly aligned layouts.

Basic Syntax#

1.parent { 2 display: grid; 3 grid-template-columns: 1fr 2fr 1fr; 4 grid-template-rows: auto auto auto; 5} 6 7.child { 8 display: grid; 9 grid-column: 1 / -1; /* Span all columns */ 10 11 /* Inherit parent's column tracks */ 12 grid-template-columns: subgrid; 13 14 /* Or inherit row tracks */ 15 grid-template-rows: subgrid; 16 17 /* Or both */ 18 grid-template-columns: subgrid; 19 grid-template-rows: subgrid; 20}

Card Grid Alignment#

1/* Parent grid */ 2.card-grid { 3 display: grid; 4 grid-template-columns: repeat(3, 1fr); 5 gap: 1.5rem; 6} 7 8/* Each card is a subgrid */ 9.card { 10 display: grid; 11 grid-template-rows: auto 1fr auto; 12 /* Fixed rows: header, content, footer */ 13} 14 15/* With subgrid for consistent heights across cards */ 16.card-grid-aligned { 17 display: grid; 18 grid-template-columns: repeat(3, 1fr); 19 /* 3 rows per card: header, content, footer */ 20 grid-template-rows: repeat(3, auto 1fr auto); 21 gap: 1.5rem 1.5rem; 22} 23 24.card-aligned { 25 display: grid; 26 grid-row: span 3; 27 grid-template-rows: subgrid; 28}

Form Layout#

1/* Form with aligned labels and inputs */ 2.form { 3 display: grid; 4 grid-template-columns: auto 1fr; 5 gap: 1rem 2rem; 6} 7 8.form-group { 9 display: grid; 10 grid-column: 1 / -1; 11 grid-template-columns: subgrid; 12 align-items: center; 13} 14 15.form-group label { 16 grid-column: 1; 17 text-align: end; 18} 19 20.form-group input { 21 grid-column: 2; 22} 23 24/* Multi-column form */ 25.form-wide { 26 display: grid; 27 grid-template-columns: auto 1fr auto 1fr; 28 gap: 1rem 2rem; 29} 30 31.form-group-wide { 32 display: grid; 33 grid-column: 1 / 3; 34 grid-template-columns: subgrid; 35} 36 37.form-group-wide.full { 38 grid-column: 1 / -1; 39}
1.nav { 2 display: grid; 3 grid-template-columns: repeat(5, auto); 4 justify-content: start; 5 gap: 1rem; 6} 7 8.nav-item { 9 display: grid; 10 grid-template-rows: auto auto; 11} 12 13/* Subgrid for dropdown alignment */ 14.nav-with-dropdown { 15 display: grid; 16 grid-template-columns: repeat(5, auto); 17 grid-template-rows: auto auto; 18} 19 20.nav-item-dropdown { 21 display: grid; 22 grid-row: 1 / 3; 23 grid-template-rows: subgrid; 24} 25 26.nav-item-dropdown .dropdown-menu { 27 grid-row: 2; 28}

Table-like Layout#

1/* Table layout with subgrid */ 2.data-table { 3 display: grid; 4 grid-template-columns: auto 1fr auto auto; 5} 6 7.table-header, 8.table-row { 9 display: grid; 10 grid-column: 1 / -1; 11 grid-template-columns: subgrid; 12} 13 14.table-header { 15 font-weight: bold; 16 border-bottom: 2px solid #e5e7eb; 17} 18 19.table-row { 20 border-bottom: 1px solid #e5e7eb; 21} 22 23.table-row:hover { 24 background-color: #f9fafb; 25} 26 27.cell { 28 padding: 0.75rem 1rem; 29}

Feature Comparison Grid#

1.comparison { 2 display: grid; 3 grid-template-columns: 1fr repeat(3, 150px); 4 gap: 0; 5} 6 7.comparison-row { 8 display: grid; 9 grid-column: 1 / -1; 10 grid-template-columns: subgrid; 11 border-bottom: 1px solid #e5e7eb; 12} 13 14.comparison-row.header { 15 font-weight: bold; 16 background-color: #f3f4f6; 17 position: sticky; 18 top: 0; 19} 20 21.comparison-cell { 22 padding: 1rem; 23 display: flex; 24 align-items: center; 25 justify-content: center; 26} 27 28.comparison-cell:first-child { 29 justify-content: flex-start; 30}

Article Layout#

1.article-layout { 2 display: grid; 3 grid-template-columns: 1fr min(65ch, 100%) 1fr; 4} 5 6.article-layout > * { 7 grid-column: 2; 8} 9 10/* Full-width elements */ 11.article-layout > .full-width { 12 grid-column: 1 / -1; 13} 14 15/* Figure with caption alignment */ 16.article-layout > figure { 17 grid-column: 1 / -1; 18 display: grid; 19 grid-template-columns: subgrid; 20} 21 22.article-layout > figure img { 23 grid-column: 1 / -1; 24} 25 26.article-layout > figure figcaption { 27 grid-column: 2; 28 padding: 1rem 0; 29}

Dashboard Grid#

1.dashboard { 2 display: grid; 3 grid-template-columns: repeat(12, 1fr); 4 grid-template-rows: auto repeat(3, 200px); 5 gap: 1.5rem; 6} 7 8.widget { 9 display: grid; 10 grid-template-rows: auto 1fr; 11 background: white; 12 border-radius: 8px; 13 overflow: hidden; 14} 15 16/* Widget spanning multiple columns with subgrid */ 17.widget-wide { 18 grid-column: span 8; 19 display: grid; 20 grid-template-columns: subgrid; 21} 22 23.widget-wide .widget-header { 24 grid-column: 1 / -1; 25} 26 27.widget-wide .widget-content { 28 grid-column: 1 / -1; 29 display: grid; 30 grid-template-columns: subgrid; 31}

Pricing Cards#

1.pricing-grid { 2 display: grid; 3 grid-template-columns: repeat(3, 1fr); 4 /* Rows: header, price, features (5), cta */ 5 grid-template-rows: auto auto repeat(5, auto) auto; 6 gap: 1.5rem; 7} 8 9.pricing-card { 10 display: grid; 11 grid-row: 1 / -1; 12 grid-template-rows: subgrid; 13 background: white; 14 border-radius: 12px; 15 padding: 2rem; 16} 17 18.pricing-card.featured { 19 background: #3b82f6; 20 color: white; 21 transform: scale(1.05); 22} 23 24.pricing-header { 25 text-align: center; 26} 27 28.pricing-price { 29 text-align: center; 30 font-size: 2.5rem; 31 font-weight: bold; 32} 33 34.pricing-features { 35 display: grid; 36 grid-row: span 5; 37 grid-template-rows: subgrid; 38} 39 40.pricing-cta { 41 align-self: end; 42}

Timeline Layout#

1.timeline { 2 display: grid; 3 grid-template-columns: auto 1fr; 4 gap: 0 2rem; 5} 6 7.timeline-item { 8 display: grid; 9 grid-column: 1 / -1; 10 grid-template-columns: subgrid; 11 padding-bottom: 2rem; 12} 13 14.timeline-marker { 15 display: flex; 16 flex-direction: column; 17 align-items: center; 18} 19 20.timeline-marker::after { 21 content: ''; 22 flex: 1; 23 width: 2px; 24 background: #e5e7eb; 25} 26 27.timeline-dot { 28 width: 12px; 29 height: 12px; 30 border-radius: 50%; 31 background: #3b82f6; 32} 33 34.timeline-content { 35 padding-bottom: 2rem; 36}

Named Grid Lines#

1.layout { 2 display: grid; 3 grid-template-columns: 4 [full-start] 5 1fr 6 [content-start] 7 min(65ch, 100%) 8 [content-end] 9 1fr 10 [full-end]; 11} 12 13.content { 14 grid-column: content; 15} 16 17.full-width-section { 18 grid-column: full; 19 display: grid; 20 grid-template-columns: subgrid; 21} 22 23.full-width-section > .inner { 24 grid-column: content; 25}

Best Practices#

When to Use: ✓ Aligning nested items with parent ✓ Card layouts with consistent parts ✓ Form label/input alignment ✓ Table-like structures ✓ Complex multi-level layouts Patterns: ✓ Span all parent columns/rows ✓ Use with named grid lines ✓ Combine with gap inheritance ✓ Match parent track count Browser Support: ✓ Check caniuse.com ✓ Provide fallbacks ✓ Use @supports ✓ Progressive enhancement Avoid: ✗ Subgrid without spanning ✗ Mismatched track counts ✗ Over-nesting grids ✗ Forgetting gap inheritance

Conclusion#

CSS subgrid enables perfect alignment between nested grids and their parents by inheriting track definitions. Use it for card grids with consistent headers and footers, form layouts with aligned labels, table-like structures, and any layout where nested items need to align with a parent grid's tracks. Remember that the child must span the parent tracks it wants to inherit, and gaps are also inherited from the parent grid.

Share this article

Help spread the word about Bootspring