Flexbox or Grid? Pick by how many axes you are laying out
“Should I use flexbox or grid?” is asked as if it were a matter of taste. It is not. Flexbox lays out content along one axis — a row or a column. Grid lays out along two — rows and columns at once. Count the axes your layout has and the answer falls out.
One axis: flexbox
A nav bar, a row of tags, a toolbar, a stack of fields — these are one-dimensional. Items flow along a line, wrap if you let them, and size from their content. Flexbox shines when items should distribute space among themselves:
.toolbar {
display: flex;
gap: 0.75rem;
align-items: center;
}
.toolbar .spacer { flex: 1; } /* eats the slack, pushing the rest to the right */
You are not positioning items on a matrix; you are arranging them on a line, and
flex-grow/flex-shrink/flex-basis decide how they share it.
Two axes: grid
A page shell, a gallery, a card layout that must align both across and down — these are two-dimensional. Grid lets you define columns and rows and place items into that matrix, and the killer feature is alignment in both directions at once:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1rem;
}
That one line also retires a pile of media queries: auto-fit fits as many
16rem columns as the container allows, then stretches them — the layout
re-columns itself as the width changes, with no breakpoint.
The tell is who decides the sizing
There is a second way to say the same thing, and it is often faster to apply.
Flexbox is content-driven: items size from their own content first, then
share the leftover space along the one axis. Grid is container-driven: you
declare the tracks up front and items flow into that fixed structure. So when
the sizing question is “let each item be as wide as it needs, then distribute
the slack” — a toolbar, a tag list — that is flexbox. When it is “carve the
container into a known shape and place things into it” — a dashboard, a photo
wall that must line up in both directions — that is grid. If you find yourself
fighting a flex layout with fixed flex-basis values on every child to force
alignment, you have really declared a set of tracks the long way round, and grid
would say it in one line.
Where people go wrong
The common mistake is nesting flexboxes to fake a grid — a row of columns, each a column of rows — then wondering why alignment drifts when content lengths differ. That drift is the tell that you have a two-axis problem and reached for a one-axis tool. The opposite (grid for a simple button row) just adds ceremony.
They compose, of course: a grid cell often contains a flex row, and a flex item is often a small grid. The point is not that one replaces the other, but that you choose per layout by counting axes rather than by habit. Once you frame it that way, the “debate” is a lookup — one line, flexbox; a matrix, grid. The data-table exercise is a good place to feel where each belongs.