
CSS Grid vs Flexbox: A Love Letter to Both (But Mostly Grid)
Real talk about CSS layout from a developer who's made every mistake. Learn when to Grid, when to Flex, and why you're probably using the wrong one.
Confession: I Used Flexbox for Everything (And Regretted It)
Let me tell you about the dashboard I built last year. Beautiful design. Complex layout. Sidebar, header, main content area, widget grid, footer.
And I built the whole thing with Flexbox.
Nesting flex containers inside flex containers inside flex containers. Negative margins. flex-wrap with calculated percentages. Media queries out the wazoo. It worked... barely.
Then the designer wanted to swap the sidebar from left to right. On mobile only. With a different order on tablet.
I spent three hours wrestling with order properties and flex-direction when I could've just... changed a couple lines of CSS with Grid.
That's when I finally admitted: I was using Flexbox for things Grid does better.
The One Thing That Finally Clicked
For the longest time, I thought Grid and Flexbox were competitors. Pick one, learn it, use it everywhere. Like choosing between React and Vue.
I was wrong. They're not competitors. They're teammates. But you gotta know which to use when.
The revelation:
- Flexbox = One dimension (row OR column)
- Grid = Two dimensions (rows AND columns together)
That's it. That's the whole thing. Once I really understood that, my layouts got so much cleaner.
When Flexbox Is the Right Choice (And Why I Love It)
Don't get me wrong—Flexbox is amazing. For certain things, it's still my go-to. Here's where it shines:
Navigation Bars (The Classic Use Case)
Navigation is inherently one-dimensional. Items flow in a line. Flexbox handles this beautifully:
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 2rem;
}
.nav-links {
display: flex;
gap: 1rem;
list-style: none;
}
Could you use Grid here? Yeah, technically. But why? Flexbox expresses the intent better: "these items flow in a line with space between them."
Card Footers (The Margin Auto Trick)
This is my favorite Flexbox pattern. Cards with content that should push the footer to the bottom:
.card {
display: flex;
flex-direction: column;
height: 100%;
}
.card-content {
/* takes up available space */
}
.card-footer {
margin-top: auto; /* magic! pushes to bottom */
}
The margin-top: auto trick still makes me smile. So elegant.
Form Rows (Label + Input Side by Side)
.form-row {
display: flex;
gap: 1rem;
align-items: center;
}
.form-row label {
flex: 0 0 120px; /* fixed width, don't grow */
}
.form-row input {
flex: 1; /* take remaining space */
}
Simple, clean, works everywhere.
Centering (The Reason We All Learned Flexbox)
Still the best way to center anything:
.center-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
Three lines. Perfect centering. This is why Flexbox won our hearts.
When Grid Saves Your Sanity (Why I Use It More Now)
Okay, now the fun part. Grid is incredible for the stuff that used to make me want to quit frontend development.
Page Layouts (The Holy Grail Made Easy)
Header, sidebar, main content, footer. The classic layout that used to require frameworks or hacky CSS:
.page-layout {
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;
gap: 1rem;
}
header {
grid-area: header;
}
aside {
grid-area: sidebar;
}
main {
grid-area: main;
}
footer {
grid-area: footer;
}
Look at that. Named areas. No floats. No clears. No calc(). And if the designer wants sidebar on the right instead? Just swap sidebar main to main sidebar. Done. Thirty seconds.
Responsive Card Grids (Without Media Queries!)
This is the one that converted me. Responsive grids without a single breakpoint:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
That's it. That's the whole responsive grid. It creates as many 300px columns as fit, stretches them to fill space, and wraps automatically.
I spent years writing media queries for this. Never again.
Magazine Layouts (Asymmetric Grids)
Remember when asymmetric editorial layouts required absolute positioning nightmares? Not anymore:
.magazine-layout {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
gap: 1rem;
}
.featured-article {
grid-column: span 2;
grid-row: span 2;
}
.ad-space {
grid-column: 4;
grid-row: span 3;
}
The featured article takes up 2x2 cells. The ad takes a full column spanning 3 rows. And it all flows naturally.
Dashboard Interfaces (Where Grid Really Shines)
Complex app layouts with headers, nav, widgets, side panels:
.dashboard {
display: grid;
grid-template-columns: 200px 1fr 300px;
grid-template-rows: 60px 1fr;
grid-template-areas:
"nav header widgets"
"nav main widgets";
height: 100vh;
}
Three columns, two rows, named areas. Try building this with Flexbox and tell me how many nested containers you need. I'll wait.
The Strategy That Actually Works
After building way too many layouts, here's my current approach:
Grid for Macro Layout
The big picture. Overall page structure. Major regions.
.app {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
height: 100vh;
}
Flexbox for Micro Layout
Components within those regions. Buttons. Form rows. Card footers.
.toolbar {
display: flex;
justify-content: space-between;
align-items: center;
}
Together They're Unstoppable
<div class="app-layout">
<aside class="sidebar">
<nav class="nav-list"><!-- Flexbox for nav items --></nav>
</aside>
<header class="header">
<div class="header-content"><!-- Flexbox for alignment --></div>
</header>
<main class="main">
<div class="card-grid"><!-- Grid for card layout --></div>
</main>
</div>
Grid handles the page structure. Flexbox handles the components. Perfect harmony.
Advanced Grid Tricks I Learned the Hard Way
minmax() Is Your Best Friend
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
This one line creates a responsive grid where each column is at least 200px but can grow to fill space. No media queries. It's magic.
Grid Template Areas Are Worth Learning
I resisted this at first. Seemed weird. Now I use it constantly:
.layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
/* Responsive: stack on mobile */
@media (max-width: 768px) {
.layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
Moving sidebar below main on mobile is just... changing the string. So much cleaner than reordering DOM elements or fighting with Flexbox order.
Subgrid Solves Alignment Headaches
This is newer (Safari 16+, Chrome 117+, Firefox 71+) but game-changing:
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
Now all card titles align, all descriptions align, and all buttons align—regardless of content length. Without fixed heights. Without JavaScript.
Browser Support in 2026: Just Use Them
Grid support: 96.5% globally. All modern browsers. Flexbox support: 99.7% globally. Basically universal.
Unless you're supporting Internet Explorer (and please, tell me you're not in 2026), you can use both without worry.
Even IE11 supported Flexbox with prefixes. Grid? Not so much. But IE11 died in 2022 when Microsoft ended support. It's had <0.5% market share for years.
Common Mistakes I See (And Made Myself)
Mistake 1: Nested Flex Hell
/* ❌ Don't do this */
.row {
display: flex;
}
.col {
display: flex;
flex-direction: column;
}
.inner-row {
display: flex;
}
/* Just use Grid */
.grid {
display: grid;
grid-template-columns: 1fr 2fr;
}
If you're nesting Flexbox more than 2 levels deep, you probably want Grid.
Mistake 2: Calculating Percentages
/* ❌ Old way */
.three-col > * {
width: 33.333%;
}
/* ✅ Grid way */
.three-col {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
Stop doing math. Let Grid handle it.
Mistake 3: Forgetting Gap
/* ❌ Margin hacks */
.flex-item {
margin-right: 1rem;
}
.flex-item:last-child {
margin-right: 0;
}
/* ✅ Just use gap */
.flex-container {
display: flex;
gap: 1rem;
}
Gap works in both Flexbox and Grid now. No more margin hacks.
Mistake 4: Using Grid for Everything
/* ❌ Overkill */
.nav {
display: grid;
grid-template-columns: repeat(5, auto);
}
/* ✅ Simple */
.nav {
display: flex;
gap: 1rem;
}
Grid is powerful, but sometimes Flexbox is just simpler. Don't over-engineer.
Real Talk: Which Should You Learn First?
If you're new to modern CSS:
- Start with Flexbox. It's simpler, more intuitive, and you'll use it constantly.
- Add Grid once you're comfortable. For page layouts and complex grids.
- Use both together. Grid for structure, Flexbox for components.
You don't have to pick one. They're complementary. Learn both, use appropriately.
The Complete Dashboard Example
Since you made it this far, here's a real-world dashboard combining both:
<div class="dashboard">
<aside class="sidebar">
<div class="logo">Dashboard</div>
<nav class="nav">
<a href="#" class="nav-item active">Overview</a>
<a href="#" class="nav-item">Analytics</a>
<a href="#" class="nav-item">Reports</a>
<a href="#" class="nav-item">Settings</a>
</nav>
</aside>
<header class="header">
<h1>Overview</h1>
<div class="header-actions">
<button>Notifications</button>
<button>Profile</button>
</div>
</header>
<main class="main">
<div class="stats-grid">
<div class="stat-card">
<h3>Total Users</h3>
<p class="stat-value">24,532</p>
</div>
<!-- More stat cards... -->
</div>
<div class="charts-grid">
<div class="chart-container large">
<h3>Sales Overview</h3>
<div class="chart">[Chart]</div>
</div>
<div class="chart-container">
<h3>Recent Activity</h3>
<ul class="activity-list">
<li>New order #1234</li>
<li>User registration</li>
</ul>
</div>
</div>
</main>
</div>
/* Grid for the overall layout */
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
min-height: 100vh;
}
/* Flexbox for components within */
.sidebar {
grid-area: sidebar;
background: #1a1a2e;
color: white;
padding: 1.5rem;
}
.nav {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.header {
grid-area: header;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 2rem;
background: white;
border-bottom: 1px solid #e0e0e0;
}
.header-actions {
display: flex;
gap: 1rem;
}
.main {
grid-area: main;
padding: 2rem;
background: #f5f5f5;
}
/* Grid for the stats */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
/* Grid for charts */
.charts-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 1.5rem;
}
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr;
grid-template-areas:
"header"
"sidebar"
"main";
}
.nav {
flex-direction: row;
flex-wrap: wrap;
}
.charts-grid {
grid-template-columns: 1fr;
}
}
See? Grid handles the big structural pieces. Flexbox handles the alignment and distribution within components. Both working together.
FAQ: Questions I Actually Get Asked
Q: Should I learn Grid or Flexbox first? A: Flexbox. It's simpler and you'll use it constantly. Add Grid once you're comfortable.
Q: Is Grid replacing Flexbox? A: Nope. They're complementary. Grid is for 2D layouts, Flexbox for 1D. Both have their place.
Q: Can I use them together? A: Absolutely! Grid for page structure, Flexbox for components. Best of both worlds.
Q: Do I still need to support IE11? A: Please no. Microsoft ended support in 2022. It has <0.5% market share. Let it die.
Q: What's the browser support for Grid? A: 96.5%+ globally. All modern browsers. You're good.
Q: When should I use floats? A: Never for layout. Floats are for text wrapping around images. Grid and Flexbox have replaced layout floats entirely.
Q: What about CSS frameworks like Bootstrap? A: Modern frameworks (Bootstrap 5+, Tailwind) use Grid and Flexbox internally. Understanding the underlying CSS makes you better at using them.
The Bottom Line
After years of building layouts, here's what I know for sure:
Grid for macro layout. Flexbox for micro layout.
Grid gives you the power to build complex, responsive layouts without hacks. Flexbox gives you simple, elegant control over one-dimensional flows.
Stop fighting your CSS. Stop using the wrong tool because it's familiar. Grid and Flexbox are both incredible—use the right one for the job.
And for the love of all that is holy, stop using float: left for layouts. We have better tools now. Use them.
Want to experiment? Try our Grid Playground where you can drag things around and see the CSS generate in real-time. It's pretty satisfying.
Happy layout building. May your divs always align perfectly.
Written by someone who's spent way too much time centering divs
Written by Axonix Team
Axonix Team - Technical Writer @ Axonix
Share this article
Discover More
View all articles
Stop Using Open Sans: A Masterclass in Font Pairing
Your content is great, but your font makes you look like a generic WordPress template. Let me fix that for you.

The Ultimate Flexbox Cheatsheet: Align Anything
Confused by 'justify-content' vs 'align-items'? You stick `display: flex` on everything and hope for the best? Here is the definitive guide to controlling layout on the web.

React 19: Practical Features That Actually Matter
React 19 is here and it's not just hype. After building with it for two months, here's what actually matters and what you can ignore.
Use These Related Tools
View all toolsFlexbox Playground
Visual CSS Flexbox builder to master responsive layouts effortlessly.
Grid Playground
Visual CSS Grid builder to prototype complex 2D layouts in seconds.
CSS Gradient Generator
Create beautiful CSS gradients.
CSS Keyframes
Visually build complex CSS animations with real-time timeline preview.
Ready to boost your productivity?
Axonix provides 20+ free developer tools to help you code faster and more securely.
Explore Our Tools