CSS Grid vs Flexbox: When to Use Each
CSS Grid and Flexbox are both powerful layout systems, but they solve different problems. Understanding when to use each makes your CSS cleaner and more maintainable.
The Key Difference
Flexbox is one-dimensional — it lays out items in a row or column. Grid is two-dimensional — it handles rows and columns together.
- Use Flexbox for alignment, navigation menus, card components
- Use Grid for page layouts, complex grids, dashboard interfaces
When to Use Flexbox
1. Navigation Bars
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
Perfect for horizontally aligning items with space distribution.
2. Centering Content
.card {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
The classic "center something both ways" pattern.
3. Card Layouts with Wrapping
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 300px; /* grow, shrink, base width */
}
Cards that fill available space but wrap to next line when needed.
4. Form Layouts
.form-row {
display: flex;
gap: 1rem;
}
.form-row input {
flex: 1;
}
Labels and inputs aligned in consistent rows.
When to Use CSS Grid
1. Page Layouts
.layout {
display: grid;
grid-template-columns: 200px 1fr 250px;
grid-template-areas: "sidebar main aside";
min-height: 100vh;
}
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
Named grid areas make the layout structure obvious.
2. Responsive Grids
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
}
Cards automatically wrap and resize without media queries!
3. Dashboard Layouts
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: auto 1fr auto;
}
.stats { grid-column: span 4; }
.chart { grid-column: span 8; }
Assign elements to specific columns and rows.
4. Gallery with Fixed Aspect Ratios
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
gap: 0.5rem;
}
.gallery-item:nth-child(4) {
grid-column: span 2;
grid-row: span 2;
}
Grid lines let you span items across multiple cells.
Common Patterns
Holy Grail Layout (Grid)
.holy-grail {
display: grid;
grid-template: auto 1fr auto / auto 1fr auto;
min-height: 100vh;
}
header { grid-area: 1 / 1 / 2 / 4; }
nav { grid-area: 2 / 1 / 3 / 2; }
main { grid-area: 2 / 2 / 3 / 3; }
aside { grid-area: 2 / 3 / 3 / 4; }
footer { grid-area: 3 / 1 / 4 / 4; }
Sticky Footer (Flexbox)
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main { flex: 1; } /* pushes footer down */
Grid Auto-Fit vs Auto-Fill
/* auto-fit: items stretch to fill space */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* auto-fill: items don't stretch, maintain base size */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
Use auto-fit when you want items to grow, auto-fill when you want them to stay compact.
Can You Mix Them?
Absolutely! The best layouts combine both:
.page {
display: grid; /* page uses grid */
grid-template-columns: 1fr;
}
.card-grid {
display: flex; /* cards inside use flexbox */
flex-wrap: wrap;
gap: 1rem;
}
Quick Reference
| Use Case | Best Choice |
|---|---|
| Navigation bar | Flexbox |
| Card grid | Grid (auto-fit) |
| Page layout | Grid |
| Button group | Flexbox |
| Form inputs | Flexbox |
| Masonry gallery | Grid |