CSS Grid: Complete Guide to Modern Layouts
Flexbox is for 1D. Grid is for 2D. Here's how to master it.
Grid vs Flexbox: When to Use Which
Need to lay out items in ONE direction?
→ Use Flexbox (row OR column)
Need to lay out items in TWO directions (rows AND columns)?
→ Use Grid
The Basics
.container {
display: grid;
}
Defining Columns and Rows
/* Fixed columns */
.grid { display: grid; grid-template-columns: 200px 200px 200px; }
/* Fractional units (equal width) */
.grid { display: grid; grid-template-columns: 1fr 1fr 1fr; }
/* Mixed */
.grid { display: grid; grid-template-columns: 250px 1fr 150px; }
/* Sidebar | Main content | Side panel */
/* repeat() shorthand */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
/* auto-fit with minmax (responsive!) */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
/* Rows */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto auto auto; /* Or let it figure out */
}
Gap
.grid {
gap: 1rem; /* Row + column gap */
row-gap: 0.5rem; /* Gap between rows */
column-gap: 1rem; /* Gap between columns */
}
Placement
Named Areas (The Cleanest Approach)
.layout {
display: grid;
grid-template-columns: 250px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
gap: 1rem;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Line-Based Placement
.item {
/* Start at column line 2, end at column line 4 */
grid-column: 2 / 4;
/* Start at row line 1, end at row line 3 */
grid-row: 1 / 3;
/* Span 2 columns */
grid-column: span 2;
/* Specific lines */
grid-column-start: 1;
grid-column-end: -1; /* Last line */
}
Alignment
.container {
/* Align all items in their cells */
justify-items: start | center | end | stretch; /* Horizontal within cell */
align-items: start | center | end | stretch; /* Vertical within cell */
/* Align the entire grid within container */
justify-content: start | center | end | space-between | space-around | space-evenly;
align-content: start | center | end | space-between | space-around | space-evenly;
}
/* Per-item override */
.specific-item {
justify-self: center;
align-self: end;
}
Common Layouts
Dashboard Grid
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.dashboard .widget {
padding: 1.5rem;
border-radius: 8px;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* Full-width widget */
.widget.wide { grid-column: span 2; }
Photo Gallery (Masonry-like)
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: 200px; /* Default height */
gap: 8px;
}
.gallery .photo:nth-child(4n+1) { grid-row: span 2; } /* Tall photos */
.gallery img { width: 100%; height: 100%; object-fit: cover; }
Responsive Card Grid
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
/* Auto-fits as many 300px+ columns as will fit */
/* On mobile: 1 column, tablet: 2 columns, desktop: 3-4 columns */
Form Layout
.form-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 1rem 0.5rem;
align-items: center;
max-width: 500px;
}
.form-grid label { font-weight: 600; }
.form-grid input, .form-grid select, .form-grid textarea {
grid-column: 2;
}
.form-grid .full-width { grid-column: 1 / -1; }
Implicit Grid (Auto-placement)
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
/* Items automatically fill cells left-to-right, top-to-bottom */
}
/* Control implicit rows */
.container {
grid-auto-rows: 200px; /* All implicit rows = 200px */
grid-auto-rows: minmax(100px, auto); /* At least 100px, grow if needed */
}
/* Change flow direction */
.container {
grid-auto-flow: column; /* Fill columns first, then rows */
grid-auto-flow: dense; /* Fill gaps (items may reorder) */
}
Subgrid (Nesting)
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.child {
/* Child's grid aligns with parent's grid! */
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
gap: inherit;
}
Quick Reference
| Property | Values | Use Case |
|---|---|---|
grid-template-columns |
repeat(n, fr) |
Define column structure |
grid-template-rows |
auto / px / fr |
Define row structure |
grid-template-areas |
"a b c" |
Named layout template |
gap |
length |
Spacing |
grid-column |
span N / start/end |
Item placement horizontal |
grid-row |
span N / start/end |
Item placement vertical |
justify-items |
start/center/end/stretch |
Item alignment in cell (H) |
align-items |
start/center/end/stretch |
Item alignment in cell (V) |
place-items |
shorthand |
Both alignments |
auto-fit |
with minmax()
|
Responsive columns |
What's your favorite Grid layout trick?
Follow @armorbreak for more CSS content.
Top comments (0)