CSS Flexbox vs Grid: When to Use Which
· 11 min read
Flexbox Basics (1D Layout)
Flexbox is designed for one-dimensional layouts — arranging items in a single row or column. It excels at distributing space and aligning items along one axis.
Core Concepts
Every Flexbox layout has a flex container (parent) and flex items (children). The container controls the direction, wrapping, and alignment of its items:
/* The flex container */
.container {
display: flex;
flex-direction: row; /* row | row-reverse | column | column-reverse */
justify-content: center; /* Main axis alignment */
align-items: center; /* Cross axis alignment */
gap: 1rem; /* Space between items */
flex-wrap: wrap; /* Allow items to wrap to next line */
}
/* Flex items */
.item {
flex: 1; /* Grow to fill available space */
/* Shorthand for: flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
}
.item-fixed {
flex: 0 0 200px; /* Don't grow, don't shrink, 200px wide */
}
Alignment Properties
/* Main axis (horizontal in row direction) */
.container {
justify-content: flex-start; /* Default: pack items to start */
justify-content: flex-end; /* Pack items to end */
justify-content: center; /* Center items */
justify-content: space-between;/* Equal space between items */
justify-content: space-around; /* Equal space around items */
justify-content: space-evenly; /* Equal space everywhere */
}
/* Cross axis (vertical in row direction) */
.container {
align-items: stretch; /* Default: stretch to fill container */
align-items: flex-start; /* Align to top */
align-items: flex-end; /* Align to bottom */
align-items: center; /* Center vertically */
align-items: baseline; /* Align text baselines */
}
Grid Basics (2D Layout)
CSS Grid is designed for two-dimensional layouts — controlling both rows and columns simultaneously. It's perfect for complex page layouts and structured content areas.
Core Concepts
/* The grid container */
.grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 columns */
grid-template-rows: auto 1fr auto; /* 3 rows */
gap: 1rem; /* Row and column gap */
/* Or separate: row-gap: 1rem; column-gap: 2rem; */
}
/* Grid items can span multiple cells */
.header {
grid-column: 1 / -1; /* Span all columns */
}
.sidebar {
grid-row: 2 / 3; /* Row 2 only */
}
.main {
grid-column: 2 / 4; /* Columns 2-3 */
grid-row: 2 / 3;
}
The fr Unit and repeat()
/* fr = fractional unit (proportion of available space) */
.grid {
grid-template-columns: 1fr 3fr; /* 25% / 75% */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* Responsive! */
grid-template-columns: 200px 1fr 200px; /* Fixed-fluid-fixed */
}
Named Grid Areas
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
🎨 Useful CSS & frontend tools
Side-by-Side Comparison
| Feature | Flexbox | Grid |
|---|---|---|
| Dimension | 1D (row OR column) | 2D (rows AND columns) |
| Content vs Layout | Content-first | Layout-first |
| Best for | Components, nav bars, cards | Page layouts, dashboards |
| Item sizing | Based on content + flex rules | Based on track definitions |
| Alignment | Along main/cross axis | Along row/column axis |
| Overlapping | Not supported | Yes (grid items can overlap) |
| Named areas | No | Yes (grid-template-areas) |
When to Use Flexbox
Flexbox is the right choice when you're working with items in a single direction:
Navigation Bars
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
Card Row with Equal Heights
.card-row {
display: flex;
gap: 1.5rem;
flex-wrap: wrap;
}
.card {
flex: 1 1 300px; /* Grow, shrink, min 300px */
display: flex;
flex-direction: column;
}
.card-body {
flex: 1; /* Push footer to bottom */
}
.card-footer {
margin-top: auto;
}
Centering Content
/* The simplest centering technique */
.center-me {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
When to Use Grid
Grid shines for two-dimensional layouts and structured designs:
Responsive Card Grid
/* Auto-responsive without media queries */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
/* Each card fills one grid cell automatically */
Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
min-height: 100vh;
}
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main";
}
.sidebar { display: none; }
}
Magazine-Style Layout
.magazine {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 1rem;
}
/* Featured article spans 2x2 */
.featured {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
/* Secondary article spans full width */
.secondary {
grid-column: 3 / 5;
}
Real Layout Examples
Holy Grail Layout (Grid)
.holy-grail {
display: grid;
grid-template: auto 1fr auto / 200px 1fr 200px;
min-height: 100vh;
}
header, footer { grid-column: 1 / -1; }
nav { grid-column: 1; }
main { grid-column: 2; }
aside { grid-column: 3; }
@media (max-width: 768px) {
.holy-grail {
grid-template-columns: 1fr;
}
nav, aside { grid-column: 1; }
}
Form Layout (Grid)
.form-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.75rem 1rem;
align-items: center;
}
label { text-align: right; }
input, select, textarea { width: 100%; }
/* Full-width submit button */
.submit-row {
grid-column: 1 / -1;
text-align: right;
}
Use our Code Formatter to clean up your CSS before committing, and our Diff Checker to compare layout changes across versions.
Combining Flexbox and Grid
The best layouts often use both. Use Grid for the overall page structure and Flexbox for components within grid cells:
/* Grid for page structure */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
}
/* Flexbox for the header inside a grid cell */
.header {
grid-column: 1 / -1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
/* Flexbox for card content inside grid items */
.card {
display: flex;
flex-direction: column;
}
.card-actions {
display: flex;
gap: 0.5rem;
margin-top: auto;
}
Browser Support
Both Flexbox and Grid have excellent browser support in 2026:
- Flexbox: 99%+ global support. Safe to use everywhere.
- CSS Grid: 97%+ global support. Safe for all modern projects.
- Subgrid: 90%+ support (Firefox, Chrome 117+, Safari 16+). Use with fallbacks.
- Container Queries: 90%+ support. Combine with Grid/Flexbox for truly responsive components.
Pick colors for your layouts with our Color Picker — generate harmonious palettes, convert between formats, and copy CSS values instantly.
Frequently Asked Questions
Should I use Flexbox or Grid for a responsive card layout?
Use Grid with repeat(auto-fill, minmax(250px, 1fr)). This creates a responsive card grid that automatically adjusts columns based on available space, without any media queries. Flexbox can work too with flex-wrap, but Grid gives you more control over column consistency.
Can I nest Flexbox inside Grid?
Absolutely! This is the recommended approach. Use Grid for the overall page layout (header, sidebar, main content, footer) and Flexbox for components within grid cells (navigation links, card content, button groups). They complement each other perfectly.
Is CSS Grid replacing Flexbox?
No. Grid and Flexbox solve different problems. Flexbox is better for 1D layouts (navbars, button groups, centering), while Grid is better for 2D layouts (page structures, dashboards). Modern CSS uses both together.
What is the gap property?
The gap property sets spacing between flex/grid items without adding margins. It works in both Flexbox and Grid. You can set row-gap and column-gap separately, or use gap as a shorthand. It's supported in all modern browsers.