CSS Grid
Create powerful two-dimensional layouts with CSS Grid — define columns and rows explicitly, place items precisely, and build responsive designs without media queries.
Grid Container Basics
CSS Grid divides a container into rows and columns. Set display: grid and define tracks with grid-template-columns and grid-template-rows. The fr unit distributes remaining space proportionally.
Grid is explicit by default — you define the structure and place items into it. This makes complex layouts readable in CSS rather than buried in nested div wrappers.
- fr units represent a fraction of available space after fixed tracks
- gap replaces grid-gap and works for both rows and columns
- Use minmax() to create flexible tracks with minimum sizes
.dashboard {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100dvh;
gap: 1rem;
}Placing Grid Items
Items can be placed explicitly with grid-column and grid-row, or implicitly by source order. Grid-template-areas provides a visual ASCII map of your layout — name regions and assign elements to them.
Named grid lines and areas make responsive refactors easier because you change the template, not individual item properties.
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }Auto-fit and Auto-fill
Repeat with auto-fit or auto-fill creates responsive grids without media queries. Combined with minmax(), columns automatically wrap when space runs out.
Auto-fit collapses empty tracks, while auto-fill preserves them. For card grids, auto-fit with minmax(280px, 1fr) is the most common responsive pattern.
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}Subgrid
Subgrid allows nested grids to inherit track sizing from their parent. This keeps card internals aligned across a row — for example, aligning action buttons at the bottom regardless of varying content height.
Subgrid support is now broad in modern browsers. Use grid-template-columns: subgrid on the child grid to participate in the parent track sizing.
- Subgrid solves the "equal height cards" problem elegantly
- Check caniuse.com for subgrid support in your target browsers
- Fallback: use flex column with margin-top: auto on actions
.card-grid > .card {
display: grid;
grid-row: span 1;
grid-template-rows: subgrid;
grid-row: span 3;
}Grid vs Flexbox Decision Guide
Use Grid when you need control over both axes simultaneously — page layouts, photo galleries, and form field arrangements. Use Flexbox for one-dimensional distribution — nav bars, button groups, and inline tags.
They compose well together. A Grid layout with Flexbox inside each cell gives you the best of both models.
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.form-actions {
display: flex;
justify-content: flex-end;
gap: 0.75rem;
grid-column: 1 / -1;
}