Flexbox or Grid — which to choose (and the sign you chose wrong)

There's a simple sign that you picked the wrong layout. It's spelled out in the MDN docs, and it goes like this:
If you're using flexbox and find yourself disabling some of the flexibility — you probably need grid.
Setting a hard width on a flex item so it lines up with the row above? Writing flex: 0 0 240px for the third time in a row? That's it. You're hand-building a grid inside a tool that doesn't do grids.
Let's find where the real boundary runs — it isn't where people usually put it.
One dimension versus two
The base difference is simple. Flexbox was designed for layout in one dimension: either a row or a column. Grid was designed for two at once: rows and columns together.
This isn't about "can flexbox wrap". It can, flex-wrap: wrap works fine. But wrapped items land on a new line and renegotiate their widths from scratch — with their neighbours on that line, knowing nothing about the line above. Which is why the columns don't line up vertically.
In grid you declare the tracks first (grid-template-columns: 1fr 1fr 1fr), and items get placed into them. The columns always match, because they exist before the items do.
The deciding question fits on one line: do I need to control both the row and the column at the same time? If yes — grid.
Content out versus layout in
This distinction is more useful than the first one, even though it comes up less often.
Flexbox works from the content out. You drop in a set of items and let their own sizes decide who takes what. The ideal case is a row of buttons of different lengths: let each be as wide as its text, and share the leftover space between them.
Grid works from the layout in. You draw the structure first, then place items into it — and they obey the tracks, not the other way around.
Hence the practical rule: if sizes should be dictated by content, use flex; if content should obey a structure, use grid.
Criteria, point by point
- Dimensions. Flex — a row or a column. Grid — rows and columns at once.
- Who decides the size. Flex — the items' content. Grid — the declared tracks.
- Columns lining up across rows. Flex — not guaranteed. Grid — always.
- Order in the markup. Flex — you can only reshuffle visually with
order. Grid — you can drop an item into a specific cell regardless of HTML order. - Spacing.
gapworks in both. The old "flexbox has no gap, use margin" advice is out of date: Firefox since 2018, Chrome since version 84, Safari since 14.1 — so universally since 2020–2021. - Alignment. Identical.
align-items,justify-content,place-itemscome from the shared Box Alignment module, not from one layout system. - Nested tracks. Only grid has
subgrid— a child grid inherits its parent's tracks (Chrome 117, Firefox 71, Safari 16). Irreplaceable when cards in a row need their headings and buttons on shared lines. - Learning curve. Flex — three properties and you're going. Grid — you need tracks,
frandminmax(), call it half an hour.
Who should take what
No fence-sitting.
Take flex for: a nav bar, a row of buttons, a list item (icon + text + button on the right), tags, a three-block footer — any strip where items line up and share space.
Take grid for: the page shell, a card gallery, pricing plans in a row, a two-column form, a dashboard, a calendar — anything where columns need to match.
Take both, because that's the norm, not a compromise: grid lays out the page and the gallery, flex handles the insides of each card. One project happily uses both on a single screen.
One more note on a common auto-grid mistake. Here's the line that makes a responsive gallery with no media queries at all:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}
Columns appear and disappear on their own as width allows. minmax(220px, 1fr) also insures you against sideways scrolling: without a lower bound, 1fr tracks bottom out at their content and refuse to shrink.
Short version: a line is flex, a grid is grid, and "I'm disabling the flexibility" means you're in the wrong tool.
Is flexbox obsolete now that grid exists?
No, they aren't competitors — they're different jobs. Grid doesn't retire flexbox any more than a table retires a list. In real projects flex shows up more often, simply because interfaces have more small linear blocks than page shells.
Can I use them together?
Not only can you — it's standard practice. A grid item happily becomes a flex container for its own children. A card sits in a grid cell, and inside it flex pins the button to the bottom.
What if I'm using Tailwind?
Exactly the same call — flex and grid there are just classes over the same CSS properties. The difference is typing speed, not layout choice; on the approach itself, see Tailwind or plain CSS.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





