CSS Grid vs Flexbox: When to Use Each Layout Method
Choose between CSS Grid and Flexbox with confidence. Learn strengths, use cases, and best practices for both with real-world examples.
CSS Grid vs Flexbox: When to Use Each Layout Method
Both CSS Grid and Flexbox are powerful layout tools, but knowing when to use each one can significantly improve your development workflow and code quality.
The Key Difference
Flexbox is one-dimensional - it works with either rows or columns at a time. CSS Grid is two-dimensional - it works with both rows and columns simultaneously.
That simple definition is useful, but real projects are rarely that clean. A pricing section may use Grid for the outer columns and Flexbox inside each card. A dashboard may use Grid for the shell, Flexbox for toolbar controls, and Grid again for the metric tiles. The best choice is usually based on which part of the layout owns the spacing decisions.
Use this rule of thumb:
- If the parent needs to control rows and columns, start with Grid.
- If the children need to flow, stretch, shrink, or align along one axis, start with Flexbox.
- If both are true, combine them instead of forcing one tool to do everything.
When to Use Flexbox
1. Navigation Bars
Perfect for horizontal navigation with items that need to be evenly distributed:
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
2. Card Layouts
When you have a collection of cards that should wrap to new lines:
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 300px; /* grow, shrink, basis */
}
3. Centering Content
The easiest way to center content both horizontally and vertically:
.center {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
When to Use CSS Grid
1. Page Layouts
Perfect for creating overall page structure:
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
}
2. Complex Card Grids
When you need precise control over card placement:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
3. Form Layouts
Great for aligning form elements in a structured manner:
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.full-width {
grid-column: 1 / -1;
}
Practical Examples
Component Layout (Flexbox)
.component {
display: flex;
align-items: center;
gap: 1rem;
}
.component__content {
flex: 1;
}
This pattern is ideal for media objects, comment rows, notification items, and compact list rows. The icon, avatar, or thumbnail keeps its natural size while the text column takes the remaining room.
.notification {
display: flex;
align-items: flex-start;
gap: 0.75rem;
}
.notification__icon {
flex: 0 0 2rem;
}
.notification__body {
flex: 1;
min-width: 0;
}
The min-width: 0 detail matters. Without it, long text inside a flex child can overflow instead of wrapping, especially in cards and sidebars.
Dashboard Layout (Grid)
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
height: 100vh;
}
.sidebar { grid-row: 1 / -1; }
.header { grid-column: 2; }
.main { grid-column: 2; }
Grid works better here because the layout is defined by named regions and stable tracks. You can change the shell at breakpoints without rewriting the markup:
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr;
}
.sidebar,
.header,
.main {
grid-column: 1;
grid-row: auto;
}
}
Common Mistakes I See in Production
Using Flexbox for True Grids
Flexbox can wrap cards, but it does not align rows as a two-dimensional system. If one card has more content than the others, the next row may look visually uneven.
/* Better for article cards, product grids, and galleries */
.article-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1.25rem;
}
Using Grid for Tiny Inline Alignment
Grid can align an icon and label, but Flexbox is usually simpler and easier to maintain for one-axis UI controls:
.button-content {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
Forgetting Content Constraints
Neither Grid nor Flexbox fixes long words, dynamic titles, or user-generated content by itself. Add width constraints and wrapping rules where content can vary:
.card-title {
overflow-wrap: anywhere;
}
.layout-column {
min-width: 0;
}
Real-World Decision Matrix
| Requirement | Best starting point | Why |
|---|---|---|
| Navbar with logo, links, and CTA | Flexbox | One horizontal axis with flexible spacing |
| Dashboard shell | Grid | Stable rows, columns, and named areas |
| Responsive card gallery | Grid | Equal columns and consistent row alignment |
| Avatar plus text row | Flexbox | Natural content flow on one axis |
| Complex form with aligned labels | Grid | Label/input alignment across rows |
| Button icon and label | Flexbox | Small one-axis alignment |
| Overlapping hero elements | Grid | Precise placement in the same area |
How I Combine Them
In a portfolio, SaaS dashboard, or content-heavy marketing page, I usually use Grid for macro layout and Flexbox for micro layout:
.page-section {
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr);
gap: 2rem;
}
.stat-card {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
This keeps the page structure predictable while letting individual components adapt to their content.
Quick Decision Guide
Use Flexbox when:
- Aligning items in a single direction
- Distributing space between items
- Creating responsive components
- You need items to grow/shrink
Use Grid when:
- Creating two-dimensional layouts
- You need precise placement control
- Building complex, structured layouts
- Working with overlapping elements
Both tools are complementary - use them together for the best results!