CSS Grid vs Flexbox: When to Use Each (with Examples)
Stop flipping a coin between Grid and Flexbox. Learn the mental model that picks the right layout tool every time, with practical CSS examples.
What you'll learn
- ✓The core difference between Grid and Flexbox
- ✓When two-dimensional layout actually matters
- ✓How content-out vs layout-in thinking helps you choose
- ✓How to combine both in a single page
- ✓Common pitfalls and quick rules of thumb
Prerequisites
- •Basic HTML and CSS familiarity
What and Why
CSS Grid and Flexbox both arrange items in a container, both handle gaps, alignment, and reordering. So when do you pick one over the other? The wrong choice usually still works, but you end up fighting the model: writing extra wrappers, magic margins, or media queries to coax it into shape.
The right choice makes layouts feel effortless and resize themselves naturally. The rule is short: Flexbox is one-dimensional, Grid is two-dimensional. Everything else is detail.
Mental Model
Flexbox arranges items along a single axis (row or column) and lets each item negotiate its size from its content outward. The container reacts to the items.
Grid carves the container into rows and columns first, then drops items into cells. The layout dictates positions; items fit into them.
Flexbox: one axis at a time
[ item ][ item ][ item ] main axis ->
Grid: rows and columns together
+-------+-------+-------+
| a | b | c |
+-------+-------+-------+
| d |
+-------+-------+-------+ A useful question: “Do I care about alignment in both dimensions at once?” If yes, Grid. If no, Flexbox.
Another lens: “Is the layout content-driven or layout-driven?” A nav bar whose items are sized by their text labels is content-driven; Flexbox. A card gallery with consistent rows and columns is layout-driven; Grid.
Hands-on Example
A header bar with logo on the left and links on the right is a classic Flexbox job:
.header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.75rem 1.25rem;
}
.header nav {
display: flex;
gap: 1rem;
}
The logo and nav are sized by their content; Flexbox keeps them on one axis with a gap and pushes them to opposite ends. No row or column math needed.
A responsive card gallery is a Grid job:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
.card {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
auto-fill plus minmax gives you a fluid number of columns: as many as fit at the minimum width, each stretched to fill. No media queries required.
Notice the cards themselves use Flexbox internally: a vertical stack of title, body, and footer. This is the typical pattern: Grid for the page-level skeleton, Flexbox for the contents of each cell.
A holy grail layout:
<div class="page">
<header>Header</header>
<nav>Nav</nav>
<main>Main</main>
<aside>Side</aside>
<footer>Footer</footer>
</div>
.page {
display: grid;
min-height: 100vh;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 1rem;
}
.page > header { grid-area: header; }
.page > nav { grid-area: nav; }
.page > main { grid-area: main; }
.page > aside { grid-area: aside; }
.page > footer { grid-area: footer; }
Named areas read like ASCII art. Swap rows for a mobile layout in a media query and the markup stays untouched.
A vertical menu with evenly distributed items:
.menu {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
One axis, content-sized items. Flexbox is exactly right.
Common Pitfalls
Using Flexbox to build a two-dimensional gallery. You end up with row wrappers, flex-wrap, and brittle width math. Grid was designed for this.
Using Grid to lay out a simple row of buttons. You write grid-template-columns: auto auto auto and wish you had just typed display: flex.
Forgetting min-width: 0 on flex items containing long text. Flex items default to min-width: auto, which means they will not shrink below their content; long URLs blow your layout out.
Misusing justify-content vs align-items. In Flexbox, justify-content aligns along the main axis, align-items on the cross. In Grid, both work in two dimensions and place-items shorthand sets them at once.
Reaching for absolute positioning to overlap two elements. In Grid, two items in the same cell overlap naturally; use z-index to control stacking. Cleaner than position: absolute.
Practical Tips
Default to Flexbox for navs, toolbars, and any list of items where one dimension is enough.
Default to Grid for page layouts, dashboards, image galleries, and anything where you can describe rows and columns explicitly.
Combine freely: page is Grid, each card is Flex, the card footer is Flex again. Nesting is fine and recommended.
Use gap instead of margins on children. It works on both Grid and Flexbox, and avoids the classic last-child margin headache.
Use subgrid (now widely supported) when child elements need to align to the parent grid’s tracks. It is the missing piece that used to make designers reach for tables.
Reach for grid-template-areas when the layout has a clear named structure. Reviewers thank you, and responsive variants become a one-line swap.
Wrap-up
Grid is for layouts that exist in two dimensions; Flexbox is for content laid out along one. Most real pages use both: Grid for the bones, Flex for the muscles. Memorize the dimensions question, default to the tool that fits, and you will stop wrestling with CSS layout and start describing it.
Related articles
- HTML & CSS CSS Subgrid Tutorial
Use CSS subgrid to align nested elements with their parent grid, perfect for card layouts, forms, and complex content where rows and columns must line up across components.
- HTML & CSS CSS Flexbox Deep Dive
A focused deep dive into CSS Flexbox: axes, sizing, alignment, growth, shrink, basis, and the small set of rules that explain most layouts.
- HTML & CSS CSS Grid: A Practical Beginner's Guide
CSS Grid is the modern tool for two-dimensional layout. This guide covers tracks, the fr unit, gaps, spans, and responsive grids — everything you need to build real page layouts.
- HTML & CSS CSS Cascade Layers and Specificity: A Calmer Mental Model
Stop fighting !important. Learn how the CSS cascade, specificity, and the new @layer rule combine to give you predictable, maintainable styles.