CSS Grid vs Flexbox — When to Use Each Layout System
CSS Grid and Flexbox solve different layout problems. Grid is for two-dimensional layouts; Flexbox is for one-dimensional alignment. Here's when to use grid vs flexbox, with...
CSS Grid and Flexbox are both powerful layout tools, but they solve different problems. The short answer: use Grid for two-dimensional layouts (rows AND columns), use Flexbox for one-dimensional layouts (a row OR a column).
Use the CSS Grid Generator to build grid layouts visually.
The core difference
Flexbox is one-dimensional — it lays out items along a single axis (row or column). Items can wrap, but the layout is fundamentally linear.
Grid is two-dimensional — it simultaneously controls rows AND columns. Items are placed in a defined grid structure.
/* Flexbox: control one axis */
.flex-container {
display: flex;
justify-content: space-between; /* main axis (horizontal) */
align-items: center; /* cross axis (vertical) */
}
/* Grid: control both axes at once */
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 200px; /* columns */
grid-template-rows: 60px 1fr 50px; /* rows */
}
When to use Grid
Full page layouts
Grid excels at defining the overall page structure:
.page {
display: grid;
min-height: 100vh;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
Card grids
Placing items in rows and columns with consistent sizing:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
Complex UI structures
When items need to span rows AND columns:
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 1rem;
}
.featured-widget {
grid-column: span 2; /* spans 2 columns */
grid-row: span 2; /* and 2 rows */
}
Overlapping elements
Grid allows items to overlap by placing them in the same cells:
.hero {
display: grid;
grid-template-areas: "content";
}
.hero-image,
.hero-text {
grid-area: content; /* Both occupy the same cell */
}
When to use Flexbox
Navigation bars
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
Centering content
.centered-card {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Button groups and toolbars
.button-group {
display: flex;
gap: 0.5rem;
align-items: center;
}
.toolbar {
display: flex;
justify-content: flex-start;
gap: 0.25rem;
flex-wrap: wrap;
}
Form layouts
.form-field {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.form-row {
display: flex;
gap: 1rem;
align-items: flex-end;
}
Items that need to grow/shrink
.sidebar-layout {
display: flex;
}
.sidebar {
flex: 0 0 240px; /* fixed width, don't grow/shrink */
}
.main-content {
flex: 1; /* take all remaining space */
}
Using both together
Grid and Flexbox are designed to be used together — Grid for the macro layout, Flexbox for micro-alignment inside grid cells:
/* Grid defines the page structure */
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr;
}
/* Flexbox aligns items inside the header */
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
}
/* Flexbox aligns items in the nav */
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
/* Grid for the card section */
.content-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
padding: 2rem;
}
/* Flexbox inside each card */
.card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
}
Side-by-side comparison
| Use Case | Grid | Flexbox |
|---|---|---|
| Full page layout | Best | Overkill |
| Card grid | Best | Works but limited |
| Navbar | Overkill | Best |
| Centering | Both work | Simpler |
| Two-column layout | Both work | Both work |
| Unknown number of items | Both (auto-fill) | Natural fit |
| Item overlapping | Best | Not designed for it |
| Equal height columns | Natural | Needs align-items: stretch |
| Item order matters | Grid (named areas) | Flex order property |
Common mistakes
Using Grid for simple centering:
/* Overkill: */
.center {
display: grid;
place-items: center;
}
/* Simpler: */
.center {
display: flex;
justify-content: center;
align-items: center;
}
Using nested Flexbox where Grid would be cleaner:
/* Complicated: */
.row { display: flex; gap: 1rem; }
.col { flex: 1; }
.row .row { margin-top: 1rem; }
/* Cleaner: */
.layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
Browser support
Both Grid and Flexbox have near-universal browser support (all modern browsers). No polyfills needed for any current browser.
Related tools
- CSS Grid Generator — generate grid layouts visually
- CSS Grid Layout Guide — complete grid reference
- Responsive Grid Layout — responsive design patterns
Related posts
- CSS Grid Template Areas — Named Grid Areas Explained — CSS grid-template-areas lets you name regions of your layout and assign elements…
- CSS Grid Auto Placement — How grid-auto-flow Works — CSS grid auto-placement automatically positions items in the grid without explic…
- CSS Grid Browser Support — What Works Where in 2025 — CSS Grid has near-universal browser support as of 2025. Here's what's supported …
- CSS Grid Layout — How to Build Two-Dimensional Layouts — CSS Grid creates two-dimensional layouts with explicit rows and columns. Here's …
- Responsive Grid Layout — Build Grids That Work on Any Screen — Responsive CSS grids adjust column counts based on available space using auto-fi…
Related tool
Visual CSS Grid layout builder. Configure columns, rows, gaps, and named areas. Live preview with copyable CSS output.
Written by Mian Ali Khalid. Part of the Frontend & Design pillar.