CSS Grid and Flexbox are the two pillars of modern web layout. Developers often treat them as interchangeable, but they solve fundamentally different problems. Flexbox excels at distributing space along a single axis — a row of navigation links or a vertical stack of cards. Grid handles two-dimensional layouts where rows and columns matter simultaneously — dashboards, galleries, and page-level structure. This guide provides side-by-side code comparisons so you can pick the right tool for every layout challenge.
The Fundamental Difference: One Axis vs Two
Flexbox operates in one direction at a time. You choose flex-direction: row or flex-direction: column, and items flow along that axis. Grid works in both directions simultaneously, letting you place items precisely on a row-and-column coordinate system.
Consider a simple navigation bar. Flexbox is the natural choice because navigation items flow horizontally in a single row.
/* Flexbox navigation */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #1a1a2e;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-links a {
color: #e6e6e6;
text-decoration: none;
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover {
color: #00d4ff;
}
Now consider a dashboard layout with a sidebar, header, main content, and footer. Grid handles this effortlessly because you need control over both rows and columns.
/* Grid dashboard layout */
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr 50px;
grid-template-areas:
"sidebar header"
"sidebar main"
"sidebar footer";
min-height: 100vh;
}
.sidebar { grid-area: sidebar; background: #16213e; }
.header { grid-area: header; background: #0f3460; }
.main { grid-area: main; padding: 2rem; }
.footer { grid-area: footer; background: #0f3460; }
Card Layouts: Grid Wins for Equal Columns
Card grids are one of the most common patterns on the web. While Flexbox can handle cards, Grid produces cleaner code with equal-height rows by default.
/* Flexbox card layout */
.cards-flex {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.cards-flex .card {
flex: 1 1 calc(33.333% - 1rem);
min-width: 280px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
}
/* Grid card layout -- cleaner */
.cards-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.cards-grid .card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
}
The Grid version uses auto-fill with minmax() to create a responsive layout that adjusts column count automatically. No media queries needed. Cards in the same row always have equal height. The Flexbox version requires calc() for widths and cards in the last row can stretch unevenly unless you add filler elements.
Content Alignment: Flexbox Shines for Centering
When you need to center content vertically and horizontally, Flexbox is more intuitive. The classic centering problem is solved in three lines.
/* Flexbox centering */
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.hero-content {
text-align: center;
color: white;
max-width: 600px;
padding: 2rem;
}
Grid can also center content, but the syntax is slightly less obvious for newcomers.
/* Grid centering */
.hero-grid {
display: grid;
place-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea, #764ba2);
}
The place-items: center shorthand is concise, but Flexbox’s justify-content and align-items vocabulary feels more readable when you are distributing multiple items with different spacing.
Where Flexbox truly dominates is distributing space between items. Consider a pricing bar with unequal sections.
/* Flexbox space distribution */
.pricing-bar {
display: flex;
gap: 1rem;
}
.pricing-bar .plan {
flex: 1;
padding: 2rem;
border: 2px solid #e0e0e0;
border-radius: 12px;
text-align: center;
}
.pricing-bar .plan.featured {
flex: 1.5;
border-color: #667eea;
background: #f8f7ff;
}
Complex Layouts: Combining Grid and Flexbox
The best layouts use both systems together. Grid handles the macro layout — page structure, section placement, and overall proportions. Flexbox handles micro layout — aligning items inside cards, spacing buttons, or centering icons next to text.
/* Grid for page structure */
.page {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
gap: 1.5rem;
padding: 1.5rem;
min-height: 100vh;
}
/* Flexbox inside a grid cell */
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.sidebar-nav a {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1rem;
border-radius: 8px;
color: #333;
text-decoration: none;
transition: background 0.2s;
}
.sidebar-nav a:hover {
background: #f0f0f0;
}
/* Stats cards inside main content */
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.stat-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem;
background: white;
border-radius: 12px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
.stat-card .value {
font-size: 2rem;
font-weight: 700;
color: #667eea;
}
.stat-card .label {
font-size: 0.875rem;
color: #888;
margin-top: 0.25rem;
}
Responsive Design Strategies
Both Grid and Flexbox handle responsive design, but their approaches differ. Grid’s auto-fill and auto-fit eliminate many media queries entirely. Flexbox relies on flex-wrap combined with min-width to reflow items.
/* Grid: responsive without media queries */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Flexbox: responsive with wrap */
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag {
padding: 0.25rem 0.75rem;
background: #e8f4f8;
border-radius: 9999px;
font-size: 0.875rem;
white-space: nowrap;
}
/* When you do need media queries with Grid */
.article-layout {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
}
@media (min-width: 768px) {
.article-layout {
grid-template-columns: 1fr 300px;
}
}
The decision framework is simple: use Grid when you care about both rows and columns, use Flexbox when you care about distributing items along a single axis, and combine them freely for complex interfaces. Neither replaces the other. Master both, and your CSS will be shorter, more readable, and easier to maintain.