CSS Grid vs Flexbox When to Use
One-dimensional flex vs two-dimensional grid — decision rules for navs, card grids, page shells, and nested layouts.
- css
- grid
- flexbox
- layout
Flexbox distributes space along one axis (row or column). Grid aligns content on rows and columns together. You will use both in the same UI: grid for the page skeleton and card matrix, flex for toolbars and chip rows inside cells.
Docs: MDN Grid vs Flexbox, Flexbox, Grid.
Decision rule
| Question | Lean |
|---|---|
| Am I lining up items in a single row or column? | Flex |
| Do I need rows and columns aligned as a system? | Grid |
| Content should dictate track size fluidly along one line? | Flex |
| I want explicit template areas / 12-column structure? | Grid |
| Toolbar: logo left, actions right? | Flex |
| Page: header / main / sidebar / footer? | Grid (or grid + flex inside) |
Flex wins
.toolbar {
display: flex;
align-items: center;
gap: 0.75rem;
}
.toolbar__actions {
margin-inline-start: auto;
display: flex;
gap: 0.5rem;
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
Nav links, form field + button rows, card footers with a primary action pushed end — all classic flex.
Grid wins
.page {
display: grid;
grid-template-columns: 16rem 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"nav main"
"footer footer";
min-height: 100dvh;
}
.page > header { grid-area: header; }
.page > nav { grid-area: nav; }
.page > main { grid-area: main; min-width: 0; }
.page > footer { grid-area: footer; }
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1rem;
}
Two-dimensional alignment (same column widths across rows, named areas, dense photo masonry with grid-auto-flow: dense) is grid territory.
Nested reality
<section class="product-grid">
<article class="card">
<div class="card__body">…</div>
<footer class="card__footer">
<span class="price">$12</span>
<button type="button">Add</button>
</footer>
</article>
</section>
.card {
display: flex;
flex-direction: column;
}
.card__footer {
display: flex;
align-items: center;
gap: 0.5rem;
margin-block-start: auto;
}
.card__footer .price {
margin-inline-end: auto;
}
Outer grid for matrix; inner flex for component chrome. Forcing everything into one model produces awkward gaps and magic numbers.
Overlap cases
- Equal-height cards in a row — both work; grid rows align by default; flex items stretch on the cross axis.
- Holy grail layout — grid areas are clearer than nested flex.
- Input + button — flex; don’t open grid for two siblings unless alignment to a larger matrix matters.
Interview out-loud
“Flex is one-dimensional: main axis distribution and cross-axis alignment. Grid is two-dimensional: rows and columns as one system. I use flex for toolbars, nav, and in-component packing; grid for page shells and card matrices. Nesting both is normal. gap works in both and beats margin hacks.”
Footguns
- Building a full page only with nested flex when grid areas are simpler.
- Using grid for a single row of buttons — flex is enough.
- Forgetting
min-width: 0/min-height: 0on nested flex/grid children that must scroll. - Mixing
floatleftovers with modern layout. - Media-query column counts when
auto-fit+minmaxwould suffice.
Quick refactor heuristic
If you are counting columns with media queries and every child should share row alignment, switch the outer layout to Grid. If you are fighting align-items on a single row of actions, stay on Flex. When in doubt for components, Flex; for pages and matrices, Grid. Revisit when a “flex wrap card row” grows explicit row/column alignment needs — that is the usual migration trigger in code review.
Related
Further reading
Related guides
- Centering Everything in CSSCenter with flex, grid, margin auto, and inset — horizontal, vertical, and both — plus the absolute-position and text-align traps.
- CSS Grid FundamentalsTwo-dimensional layout with tracks, gaps, placement, fr units, and when grid beats flex for page scaffolding.
- Flexbox FundamentalsFlex container vs items, main vs cross axis, grow/shrink/basis, alignment, wrapping, and the bugs that show up in real layouts.
- Auto-fit vs Auto-fillauto-fit collapses empty tracks; auto-fill keeps them. Use both with minmax for responsive card grids without media-query soup.
- CSS Box ModelContent, padding, border, margin, box-sizing, and how the math actually works for layout and overflow.