Article
Developer·13 min read·
CSS Grid vs. Flexbox: When to Use Each One (With Real Examples)
Flexbox and CSS Grid are both layout tools but they solve different problems. Learn when to reach for each, how to combine them, and stop second-guessing layout decisions.
SimpleWebToolsBox Team

Table of Contents
The Question That Trips Up Every CSS Developer
You are building a layout and you need to position some elements. Should you use Flexbox or CSS Grid? The answer you get from searching online is usually "it depends" — which is accurate but unhelpful. What does it actually depend on?
The real answer is simple once you understand what each tool was designed to solve. They are not competing alternatives to the same problem. They are complementary tools for genuinely different layout challenges. Once you see the distinction, you will stop second-guessing layout choices and start reaching for the right tool instinctively.
The Fundamental Difference in One Sentence
Flexbox is one-dimensional. It arranges items along a single axis — either a row or a column — and lets items expand, shrink, and wrap based on available space.
CSS Grid is two-dimensional. It arranges items across both rows and columns simultaneously, with explicit control over both dimensions at once.
That single distinction explains most layout decisions. If you need to align a row of buttons, distribute navigation links, or center something in a container — that is a one-dimensional problem, reach for Flexbox. If you need to position elements across a page layout with rows and columns both mattering — that is a two-dimensional problem, reach for Grid.
Flexbox: What It Does Well
Flexbox was designed for laying out items in a line — a row or a column — and managing how they distribute space and align with each other.
The Core Properties
On the container:
.container {
display: flex;
flex-direction: row; /* row | column | row-reverse | column-reverse */
justify-content: space-between; /* Main axis alignment */
align-items: center; /* Cross axis alignment */
flex-wrap: wrap; /* Allow items to wrap to next line */
gap: 16px; /* Space between items */
}
On the items:
.item {
flex: 1; /* Grow to fill space equally */
flex: 0 0 200px; /* Don't grow, don't shrink, be 200px */
align-self: flex-start; /* Override container's align-items for this item */
order: 2; /* Change visual order without changing HTML order */
}
When Flexbox Is the Right Choice
Navigation bars. A horizontal nav with a logo on the left and links on the right: display: flex; justify-content: space-between; align-items: center;. Done in three properties.
Button groups. A row of buttons with even spacing or stretching to fill a container.
Card components (internal layout). Inside a card component, Flexbox handles the layout of an image, title, description, and CTA button stacked vertically — with the button pushed to the bottom using margin-top: auto.
Centering. The classic "center something both horizontally and vertically" problem: display: flex; justify-content: center; align-items: center;. This replaced dozens of lines of older CSS hacks.
Wrapping item lists. A collection of tags, badges, or chips that should wrap to the next line when they run out of horizontal space: display: flex; flex-wrap: wrap; gap: 8px;.
Icon + text pairings. An icon next to a label: display: flex; align-items: center; gap: 8px;. This is the Flexbox use case you will write most often.
A Real Flexbox Example: Navigation Bar
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 64px;
}
.nav-links {
display: flex;
gap: 32px;
list-style: none;
}
<nav class="navbar">
<div class="logo">Brand</div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<button class="cta">Sign Up</button>
</nav>
No floats, no absolute positioning, no hacks. The logo, links, and button are evenly distributed because justify-content: space-between pushes the first and last items to the edges and spaces the rest between them.
CSS Grid: What It Does Well
Grid was designed for two-dimensional layouts where you need to define both rows and columns and place elements into the resulting cells. It shines at page-level layouts and any situation where you need items to align across both axes simultaneously.
The Core Properties
On the container:
.container {
display: grid;
grid-template-columns: 240px 1fr; /* Sidebar + main content */
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); /* Responsive grid */
grid-template-rows: auto 1fr auto; /* Header, main, footer */
gap: 24px; /* Row and column gap */
}
On the items:
.item {
grid-column: 1 / 3; /* Span from column line 1 to line 3 (2 columns wide) */
grid-row: 2 / 4; /* Span from row line 2 to line 4 (2 rows tall) */
grid-column: 1 / -1; /* Span all columns */
}
When Grid Is the Right Choice
Page-level layout. A page with a header, sidebar, main content area, and footer — items arranged across both rows and columns — is a two-dimensional problem. Grid defines this in a few lines.
Card grids. A collection of equal-width cards in rows that should align with each other horizontally — not just wrap, but actually sit in a proper grid. Flexbox wrap cannot guarantee alignment across rows. Grid can.
Magazine/editorial layouts. A feature article that spans the full width while two shorter articles sit side by side below it. Grid's grid-column: span 2 makes this trivial.
Dashboard layouts. Multiple widgets of varying sizes arranged in a defined grid — some spanning two columns, some occupying a single cell.
Overlapping elements. Grid allows placing multiple items in the same cell, enabling overlapping layouts that would be complex to achieve otherwise.
A Real Grid Example: Page Layout
.page {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 60px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 0;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
<div class="page">
<header class="header">...</header>
<nav class="sidebar">...</nav>
<main class="main">...</main>
<footer class="footer">...</footer>
</div>
The grid-template-areas syntax is one of the most readable layout declarations in CSS — you can literally see the layout in the code. No floats, no absolute positioning, no clearfix.
Responsive Grid Without Media Queries
One of Grid's most powerful features is the auto-fill + minmax pattern for creating a responsive card grid:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
This tells the browser: "Create as many columns as fit, each at least 280px wide, and let them expand to fill available space." On a wide screen, you get 4 columns. On a tablet, 3. On a phone, 1. No media queries needed.
Combining Both: The Professional Approach
In a real project, you will use Grid and Flexbox together constantly. They compose naturally because they operate on different levels of the layout:
- Grid handles the macro layout — the overall page structure, the grid of cards.
- Flexbox handles the micro layout — the internal layout of each component, alignment of items within cells.
/* Grid controls the page structure */
.page-layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: auto 1fr auto;
}
/* Flexbox controls the card's internal layout */
.card {
display: flex;
flex-direction: column;
gap: 12px;
}
.card .cta-button {
margin-top: auto; /* Push button to bottom of card */
}
/* Flexbox controls the navbar items */
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
}
A single component tree will often have Grid three levels up, Flexbox two levels up, and another Flexbox inside that. This is normal and intended — the tools compose well.
The Decision Flowchart
When you are about to write a layout, ask yourself:
1. Am I arranging items along a single line (row or column)? → Flexbox
2. Am I arranging items across a defined grid of rows AND columns? → Grid
3. Do I need items in multiple rows to align with each other horizontally? → Grid (Flexbox wrapping cannot guarantee cross-row alignment)
4. Do I need items to grow and shrink based on available space along one axis? → Flexbox (the flex-grow/flex-shrink model)
5. Am I laying out the internal content of a single component? → Usually Flexbox
6. Am I defining a page section or a collection of repeated components? → Usually Grid
Common Mistakes
Using Flexbox for Everything (Even 2D Problems)
Flexbox can be coerced into two-dimensional layouts with enough flex-wrap and calc(), but the result is fragile, hard to maintain, and missing the alignment guarantees Grid provides. If you find yourself fighting Flexbox to make a grid, switch to Grid.
Using Grid for Everything (Even 1D Problems)
Grid is more verbose for simple one-dimensional alignment. Writing a grid to center a button or align icon + text is more code than the Flexbox equivalent, with no benefit.
Forgetting gap
Both Grid and Flexbox support the gap property (previously grid-gap). Using margin on items for spacing creates complications at the edges. Use gap on the container instead.
Forgetting About the Implicit Grid
When you define grid-template-columns but add more items than expected, Grid creates implicit rows to accommodate them. These rows default to auto height, which can lead to uneven row heights. Control this with grid-auto-rows: 1fr or grid-auto-rows: minmax(100px, auto).
Not Using grid-template-areas for Complex Layouts
Named areas make complex layouts dramatically more readable and maintainable. They also make reordering for different breakpoints much cleaner than adjusting grid-column and grid-row values everywhere.
Browser Support in 2026
Both Flexbox and CSS Grid have near-universal browser support. Flexbox has been stable since 2016. CSS Grid has been stable since 2017. Sub-grid (where a grid item can also adopt its parent's grid tracks) reached broad support in 2023. There is no need to provide fallbacks for any modern browser.
Summary
- Flexbox: One-dimensional layout along a row or column. Items grow, shrink, and wrap within that axis. Use for components: navbars, button groups, card internals, centering.
- Grid: Two-dimensional layout across rows and columns simultaneously. Use for page structures, card grids, and any layout where you need cross-row alignment.
- They compose naturally: Grid handles macro structure, Flexbox handles micro component layout.
auto-fill+minmaxcreates responsive grids without media queries.grid-template-areasmakes complex layouts readable at a glance.- Browser support for both is universal. Use them without hesitation.
Stop thinking of them as competitors. Think of them as a screwdriver and a hammer — you reach for each based on what the job actually requires, and you often need both on the same project.
Content Tracking Log
| Title | Primary Keyword |
|---|---|
| CSS Grid vs. Flexbox: When to Use Each One (With Real Examples) | CSS Grid vs Flexbox |
Continue reading
Related Posts

Developer
JSON vs. CSV: Which Data Format Should You Choose?
JSON and CSV both store data, but they serve very different needs. Learn when to use each format and how to convert between them instantly.
SimpleWebToolsBox Team · May 3, 2026

Developer
Cookies vs Sessions vs Local Storage: Web Storage Explained
Every website stores data on your browser — but cookies, sessions, and local storage work very differently. Learn when to use each, security risks, and real code examples.
SimpleWebToolsBox Team · May 1, 2026

Developer
SEO Meta Tags: The Complete Guide to Title, Description & Open Graph
Meta tags control how your pages appear in Google search and social media. Learn every tag that matters, the exact character limits, common mistakes, and how to write them well.
SimpleWebToolsBox Team · Apr 21, 2026