• 7 min read • By Sarah Chen
CSS Grid vs Flexbox: When to Use Each
Master CSS layout with this comprehensive guide to Grid and Flexbox. Learn when to use each layout system and how to combine them effectively.
CSS Grid Flexbox Layout Design
The Core Difference
Flexbox is one-dimensional (row OR column) Grid is two-dimensional (rows AND columns)
When to Use Flexbox
Flexbox excels at distributing items along a single axis.
Navigation Bars
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
}
Card Content
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-content {
flex: 1; /* Grows to fill space */
}
.card-actions {
margin-top: auto; /* Push to bottom */
}
Centering Content
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Form Controls
.form-group {
display: flex;
align-items: center;
gap: 1rem;
}
.form-group label {
flex-shrink: 0;
width: 120px;
}
.form-group input {
flex: 1;
}
When to Use Grid
Grid is perfect for two-dimensional layouts.
Page Layouts
.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;
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Image Galleries
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Pinterest-style masonry (with grid) */
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: 10px;
gap: 1rem;
}
.masonry-item {
grid-row-end: span var(--row-span);
}
Card Grids
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 2rem;
}
/* Responsive without media queries! */
Dashboard Layouts
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1.5rem;
}
.widget-large {
grid-column: span 8;
}
.widget-small {
grid-column: span 4;
}
.widget-full {
grid-column: 1 / -1;
}
Flexbox Deep Dive
Main Properties
.flex-container {
display: flex;
/* Direction */
flex-direction: row | row-reverse | column | column-reverse;
/* Wrapping */
flex-wrap: nowrap | wrap | wrap-reverse;
/* Main axis alignment */
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
/* Cross axis alignment */
align-items: stretch | flex-start | flex-end | center | baseline;
/* Multi-line cross axis */
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
/* Gap (modern) */
gap: 1rem;
}
Item Properties
.flex-item {
/* Growth factor */
flex-grow: 0; /* default */
/* Shrink factor */
flex-shrink: 1; /* default */
/* Base size */
flex-basis: auto; /* default */
/* Shorthand */
flex: 1; /* grow shrink basis */
flex: 0 0 200px; /* fixed width */
/* Individual alignment */
align-self: auto | flex-start | flex-end | center | baseline | stretch;
/* Order */
order: 0; /* default */
}
Practical Flexbox Patterns
/* Equal width columns */
.columns {
display: flex;
}
.column {
flex: 1;
}
/* Sidebar layout */
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px;
}
.main {
flex: 1;
}
/* Sticky footer */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1;
}
/* Holy grail layout */
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.hg-body {
display: flex;
flex: 1;
}
.hg-sidebar {
flex: 0 0 200px;
order: -1;
}
.hg-content {
flex: 1;
}
.hg-aside {
flex: 0 0 200px;
}
Grid Deep Dive
Defining Grids
.grid {
display: grid;
/* Columns */
grid-template-columns: 200px 1fr 200px;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-columns: 1fr 2fr 1fr;
/* Rows */
grid-template-rows: auto 1fr auto;
grid-auto-rows: minmax(100px, auto);
/* Gaps */
gap: 1rem;
column-gap: 2rem;
row-gap: 1rem;
/* Areas */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
Placing Items
.grid-item {
/* Line-based placement */
grid-column: 1 / 3;
grid-row: 2 / 4;
/* Span */
grid-column: span 2;
grid-row: span 3;
/* Shorthand */
grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
/* Named area */
grid-area: header;
}
Alignment
.grid {
/* Align items (within their cell) */
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items: center; /* both */
/* Align grid (within container) */
justify-content: start | end | center | stretch | space-between | space-around | space-evenly;
align-content: start | end | center | stretch | space-between | space-around | space-evenly;
place-content: center; /* both */
}
.grid-item {
/* Individual alignment */
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
place-self: center; /* both */
}
Advanced Grid Patterns
/* Responsive grid without media queries */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 1rem;
}
/* RAM (Repeat, Auto, Minmax) */
.ram {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
/* Sidebar always visible */
.sidebar-grid {
display: grid;
grid-template-columns: minmax(200px, 300px) minmax(0, 1fr);
}
/* Asymmetric grid */
.asymmetric {
display: grid;
grid-template-columns: 2fr 1fr;
grid-auto-rows: minmax(150px, auto);
}
Combining Grid and Flexbox
Often the best solution uses both!
/* Grid for overall layout */
.page {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* Flexbox for header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
/* Grid for main content */
.main {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
/* Flexbox for cards */
.card {
display: flex;
flex-direction: column;
}
.card-body {
flex: 1;
}
.card-actions {
display: flex;
gap: 1rem;
justify-content: flex-end;
}
Real-World Examples
Blog Layout
.blog-layout {
display: grid;
grid-template-columns: 1fr min(65ch, 100%) 1fr;
}
.blog-layout > * {
grid-column: 2;
}
.full-bleed {
grid-column: 1 / -1;
}
Pricing Cards
.pricing-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.pricing-card {
display: flex;
flex-direction: column;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 8px;
}
.pricing-features {
flex: 1;
margin: 2rem 0;
}
.pricing-cta {
margin-top: auto;
}
Responsive Navigation
.nav {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.nav-links {
display: flex;
flex-wrap: wrap;
gap: 2rem;
list-style: none;
}
@media (max-width: 768px) {
.nav {
flex-direction: column;
}
.nav-links {
flex-direction: column;
width: 100%;
}
}
Performance Tips
/* Avoid unnecessary grid items */
/* Bad */
.wrapper {
display: grid;
}
.wrapper > div {
/* Each div is a grid item */
}
/* Good - only when needed */
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/* Use gap instead of margins */
/* Bad */
.grid > * {
margin: 1rem;
}
/* Good */
.grid {
gap: 1rem;
}
Browser Support
Both Grid and Flexbox have excellent browser support:
- Flexbox: 98%+ support
- Grid: 96%+ support
Use feature queries for fallbacks:
.layout {
/* Flexbox fallback */
display: flex;
flex-wrap: wrap;
}
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
Quick Decision Guide
Use Flexbox when:
- Content flows in one direction
- Items should wrap
- You need flexible spacing
- Centering content
- Navigation menus
Use Grid when:
- Two-dimensional layout needed
- Complex alignment required
- Overlapping elements
- Responsive design without media queries
- Page layouts
Conclusion
Both Grid and Flexbox are powerful tools in modern CSS. Understanding when to use each—and how to combine them—is key to creating flexible, maintainable layouts. Start with Grid for page structure, then use Flexbox for component internals.