CSS Grid vs Flexbox: When to Use What (Finally Explained)
I spent years confused about when to use Grid vs Flexbox. Then it clicked: Grid for 2D, Flexbox for 1D. But that’s oversimplified. Let’s dig deeper.
The One-Liner
- Flexbox: One direction (row OR column)
- Grid: Two directions (rows AND columns)
But real layouts are messier than theory, so here’s my practical decision tree.
Use Flexbox When…
1. You Have a Row or Column of Things
/* Navigation bar */
.nav {
display: flex;
gap: 1rem;
}
/* Vertical list */
.sidebar {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
Perfect for:
- Navigation menus
- Button groups
- Card content (title, description, button stacked)
- Toolbars
2. You Want Items to Wrap
.tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
Tags, chips, badges—they flow like text and wrap naturally.
3. You Need Items to Grow/Shrink
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px; /* Don't grow, don't shrink, stay 250px */
}
.main {
flex: 1; /* Take all remaining space */
}
Flexbox excels at distributing space.
4. You’re Centering Something
.center-me {
display: flex;
justify-content: center;
align-items: center;
}
The classic. Works every time.
Use Grid When…
1. You Have Actual Rows AND Columns
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
gap: 1rem;
}
Perfect for:
- Dashboards
- Photo galleries
- Card grids with consistent alignment
- Form layouts
2. You Need Items to Line Up Across Rows
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
All cards stay aligned even with different content heights.
3. You’re Creating Complex Layouts
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
/* etc */
Named areas make complex layouts readable.
4. You Want Responsive Without Media Queries
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1rem;
}
This auto-responds to screen size. Magic! ✨
When Either Works
Card with Content
Flexbox approach:
.card {
display: flex;
flex-direction: column;
}
.card-content {
flex: 1;
}
Grid approach:
.card {
display: grid;
grid-template-rows: auto 1fr auto;
}
Both work! Pick whichever feels more intuitive.
Common Patterns
Pattern 1: Holy Grail Layout
body {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
main {
display: grid;
grid-template-columns: 200px 1fr 200px;
gap: 2rem;
}
Grid makes this trivial. Would be painful with floats (remember those?).
Pattern 2: Responsive Navigation
.nav {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
}
}
Flexbox shines here.
Pattern 3: Image Gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
Grid keeps everything aligned perfectly.
My Decision Process
- Is it one-dimensional? → Flexbox
- Is it a grid of items? → Grid
- Do items need to line up across rows? → Grid
- Do items need to wrap and flow? → Flexbox
- Still not sure? → Try Flexbox first, it’s simpler
The Gotchas
Flexbox
- Can’t easily align items across rows
- Wrapping can create uneven gaps
- Source order matters more
Grid
- Steeper learning curve
- Overkill for simple one-directional layouts
- Browser support is great now, but check your needs
Can You Use Both?
YES! Common pattern:
.page {
display: grid; /* Page layout */
grid-template-columns: 250px 1fr;
}
.nav {
display: flex; /* Navigation items */
gap: 1rem;
}
.card-grid {
display: grid; /* Card layout */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.card {
display: flex; /* Card content */
flex-direction: column;
}
Use the right tool for each job!
Quick Reference
Flexbox:
justify-content- Main axis (horizontal by default)align-items- Cross axis (vertical by default)gap- Space between itemsflex- How items grow/shrink
Grid:
grid-template-columns- Column sizinggrid-template-rows- Row sizinggap- Space between cellsgrid-area- Named areas
Tools I Use
- Firefox DevTools - Best Grid inspector
- Chrome DevTools - Great Flexbox inspector
- CSS Grid Generator - gridbyexample.com
- Flexbox Froggy - Learn Flexbox by playing
Conclusion
Don’t overthink it. Start with Flexbox for simple layouts, reach for Grid when you need 2D control. And remember: you can always refactor later.
Now go build something! And when someone asks “Grid or Flexbox?”, you’ll know exactly what to say: “Depends!”
Happy layouting! 🎨