CSS Grid vs Flexbox: When to Use Each Layout System
CSS Grid and Flexbox are powerful layout systems, but knowing when to use each one is crucial. Let’s explore their differences and use cases.
Quick Comparison
| Feature | Flexbox | Grid |
|---|---|---|
| Dimension | 1D (row OR column) | 2D (rows AND columns) |
| Use Case | Component layout | Page layout |
| Alignment | Content-first | Layout-first |
| Browser Support | Excellent | Excellent |
Flexbox: One-Dimensional Layouts
Flexbox excels at distributing space along a single axis.
Basic Flexbox
.container {
display: flex;
gap: 1rem;
}
.item {
flex: 1; /* Equal width items */
}
Common Flexbox Patterns
1. Navigation Bar
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
<nav class="nav">
<div class="logo">Logo</div>
<ul class="nav-links">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
2. Card Layout
.card {
display: flex;
flex-direction: column;
gap: 1rem;
}
.card-header {
flex-shrink: 0;
}
.card-body {
flex: 1; /* Takes remaining space */
}
.card-footer {
flex-shrink: 0;
margin-top: auto; /* Push to bottom */
}
3. Centered Content
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
4. Responsive Toolbar
.toolbar {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.toolbar-left {
display: flex;
gap: 0.5rem;
margin-right: auto;
}
.toolbar-right {
display: flex;
gap: 0.5rem;
}
Flexbox Properties Cheatsheet
Container:
.flex-container {
display: flex; /* or inline-flex */
flex-direction: row; /* row, column, row-reverse, column-reverse */
flex-wrap: wrap; /* nowrap, wrap, wrap-reverse */
justify-content: center; /* flex-start, flex-end, center, space-between, space-around */
align-items: center; /* flex-start, flex-end, center, baseline, stretch */
align-content: center; /* flex-start, flex-end, center, space-between, space-around, stretch */
gap: 1rem;
}
Items:
.flex-item {
flex-grow: 1; /* Growth factor */
flex-shrink: 1; /* Shrink factor */
flex-basis: auto; /* Initial size */
flex: 1; /* Shorthand: grow shrink basis */
align-self: center; /* Override align-items */
order: 0; /* Visual order */
}
CSS Grid: Two-Dimensional Layouts
Grid is perfect for complex layouts with rows and columns.
Basic Grid
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
gap: 1rem;
}
Common Grid Patterns
1. Holy Grail Layout
.layout {
display: grid;
grid-template-areas:
"header header header"
"nav 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; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
2. Responsive Image Gallery
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.gallery img {
width: 100%;
height: 200px;
object-fit: cover;
}
3. Dashboard Layout
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1.5rem;
}
.widget-large {
grid-column: span 8;
}
.widget-medium {
grid-column: span 4;
}
.widget-small {
grid-column: span 3;
}
4. Magazine Layout
.magazine {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 200px;
gap: 1rem;
}
.article-featured {
grid-column: span 4;
grid-row: span 2;
}
.article-secondary {
grid-column: span 2;
}
.article-tertiary {
grid-column: span 2;
}
Grid Properties Cheatsheet
Container:
.grid-container {
display: grid; /* or inline-grid */
/* Columns & Rows */
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
/* Named Areas */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
/* Auto sizing */
grid-auto-columns: 1fr;
grid-auto-rows: 100px;
grid-auto-flow: row; /* row, column, dense */
/* Gaps */
gap: 1rem; /* shorthand */
row-gap: 1rem;
column-gap: 1rem;
/* Alignment */
justify-items: start; /* start, end, center, stretch */
align-items: start;
justify-content: start; /* start, end, center, stretch, space-between, space-around */
align-content: start;
}
Items:
.grid-item {
/* Position */
grid-column: 1 / 3; /* start / end */
grid-row: 1 / 2;
grid-area: header; /* Named area */
/* Span */
grid-column: span 2;
grid-row: span 3;
/* Alignment */
justify-self: center; /* start, end, center, stretch */
align-self: center;
}
When to Use What?
Use Flexbox When:
✅ Navigation menus
.nav {
display: flex;
justify-content: space-between;
}
✅ Centering content
.center {
display: flex;
justify-content: center;
align-items: center;
}
✅ Equal-height columns
.columns {
display: flex;
}
.column {
flex: 1;
}
✅ Component layouts (buttons, cards, forms)
Use Grid When:
✅ Page layouts
.page {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
}
✅ Image galleries
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
✅ Complex dashboards
✅ Magazine-style layouts
Combining Both
Often, the best solution uses both:
/* Grid for page layout */
.page {
display: grid;
grid-template-columns: 250px 1fr;
gap: 2rem;
}
/* Flexbox for navigation */
.nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
/* Grid for content cards */
.content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* Flexbox inside each card */
.card {
display: flex;
flex-direction: column;
}
Real-World Example
<div class="app">
<header class="header">
<nav class="nav">
<div class="logo">Logo</div>
<ul class="nav-links">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<aside class="sidebar">
<ul class="menu">
<li>Dashboard</li>
<li>Settings</li>
</ul>
</aside>
<main class="main">
<div class="cards">
<div class="card">
<h2>Card Title</h2>
<p>Content</p>
<button>Action</button>
</div>
</div>
</main>
<footer class="footer">Footer</footer>
</div>
/* Grid for overall layout */
.app {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* Flexbox for header navigation */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
/* Flexbox for sidebar menu */
.menu {
display: flex;
flex-direction: column;
gap: 0.5rem;
list-style: none;
}
/* Grid for cards */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
/* Flexbox inside cards */
.card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1.5rem;
border: 1px solid #ccc;
border-radius: 8px;
}
.card button {
margin-top: auto; /* Push to bottom */
}
Browser DevTools
Both Chrome and Firefox have excellent DevTools for debugging:
- Grid: Shows grid lines and areas
- Flexbox: Shows flex direction and alignment
Conclusion
- Flexbox: One-dimensional layouts, component-level
- Grid: Two-dimensional layouts, page-level
- Both: Use together for best results
Start with Grid for your overall page structure, then use Flexbox for individual components. This combination gives you the flexibility and power to build any layout!