Flexbox vs Grid: When to Use Each (With Examples)
Abhay Khant
Jan 1, 1970 • 7 min read
Flexbox vs Grid: When to Use Each (With Examples)
- Flexbox is one-dimensional; grid is two-dimensional
- Content-first sizing versus container-first planning
- Start with grid for the page skeleton, then flexbox inside components
- Both systems in one stylesheet is the normal end state
The core difference between flexbox and grid
The flexbox vs grid question resolves once you hold one idea: flexbox lays out items along a single axis, either a row or a column, while grid lays items out on both axes at once.
That single-dimensional versus two-dimensional distinction drives everything else, including which problems each solves naturally. As [MDN's guide to their relationship](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Relationship_of_Grid_Layout) puts the contrast, flexbox works from the content outward while grid works from the layout inward.
Concretely: a flex container asks "how wide are my children?" and distributes leftover space around them. A grid container asks "how many columns and rows do I have?" and drops children into the cells. Neither approach is better; they answer different questions, which is why the choice depends on what you know about the layout before you start.
The same layout in both systems
A three-column card row makes the difference visible. In grid, you describe the tracks:
.cards {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 1rem;
}
In flexbox, you line items up and let them share space:
.cards {
display: flex;
gap: 1rem;
}
.cards > * {
flex: 1;
}
Both use gap for spacing, [now standard across both layout systems](https://developer.mozilla.org/en-US/docs/Web/CSS/gap), so no margin hacks are needed. Both produce three equal columns today. They diverge tomorrow: when a fourth card arrives, the flexbox row squeezes four items into the same width or wraps (with flex-wrap), while the grid keeps three columns and flows the fourth into a second row automatically. If the design intent is "always exactly three columns," grid states that intent directly. If the intent is "these cards share space, however many there are," flexbox expresses it better.
A decision table instead of a verdict
| Layout problem | Reach for | Why |
|---|---|---|
| Page skeleton: header, sidebar, main, footer | Grid | Two-dimensional structure with named areas |
| Navbar items spread left and right | Flexbox | One-axis distribution is its core skill |
| Card gallery with strict column count | Grid | Track definitions enforce the count |
| Button group or form row | Flexbox | Content-sized items, easy spacing |
| Dashboard with spanning widgets | Grid | Line-based and area-based placement |
| Centering anything | Either | Both center cleanly on their axes |
When both answers look plausible, ask what happens when content changes. The system whose behavior under surprise matches the design intent is the right one.
When flexbox wins
Flexbox excels wherever a single line of content needs distribution ([MDN's flexbox overview](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_Concepts_of_Flexbox) covers the axis model): navigation bars, button rows, tag lists, form field rows, and media objects with an image beside text. Its content-first sizing means items keep their natural width until told otherwise, which suits interfaces where labels and controls vary. Wrapping with flex-wrap produces tag-cloud behavior that grid cannot match query-free, since grid's auto-fit trick only yields equal-width tracks, not variable-width ones. Per the [MDN flexbox guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout), alignment properties like justify-content and align-items ([MDN's box alignment guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_box_alignment/Aligning_Items_in_a_Flex_Container) documents the full set) handle the spacing decisions that used to require margin hacks.
Inside a card component, flexbox aligns the title, body, and footer along one axis while letting content length vary. That is the component-internal case where it beats grid on simplicity every time.
When grid wins
Grid owns two-dimensional structure. Page skeletons with headers, sidebars, and footers map directly onto [grid template areas](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout), where named regions make the layout readable in the CSS itself. The fr unit [defined in the CSS Grid specification](https://www.w3.org/TR/css-grid-1/#fr-unit) distributes free space fractionally, so 1fr 2fr gives one column twice the share without pixel math. Galleries that must show exactly four columns at every width, dashboards where widgets span multiple cells, and magazine-style arrangements all express naturally in grid and awkwardly in anything else.
Placement is grid's quiet superpower, built on [line-based placement](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Line-based_Placement_with_CSS_Grid): items can sit at explicit line numbers or named areas regardless of source order, which solves visual-order versus DOM-order mismatches that flexbox handles poorly.
Using both together
The mature answer to flexbox versus grid is usually both. Grid defines the page skeleton: a header band, a content area split into main and sidebar, a footer. Inside each region, flexbox arranges the components: a navbar's items, a card's internals, a form row. This composition mirrors how designers think, structure first then details, and it keeps each stylesheet small because each system handles what it is good at.
These generators exist on our site precisely because this decision comes up on every project: the CSS grid layout generator, then tune component internals with the flexbox generator; both output copy-ready CSS. When the stylesheet ships, the CSS minifier strips the whitespace before deployment.
CSS grid vs flexbox for responsive layouts
The responsive question has a cleaner answer than most expect, and it splits by column behavior. When columns should stay equal and the count should adapt, grid's repeat(auto-fit, minmax(240px, 1fr)) delivers responsive columns with no media queries at all. One subtlety matters here: auto-fit collapses empty tracks entirely, so a three-item gallery using it stretches those three items across the full width, while auto-fill keeps the empty tracks and preserves the column rhythm. Choosing between them is a one-word decision with visible consequences.
When items have genuinely variable widths, tags, chips, filter buttons, flexbox with flex-wrap remains the right tool, because every item keeps its natural size and rows form wherever they break. Equal-width grid tracks cannot fake that behavior. The honest summary: query-free responsiveness for uniform columns comes from grid, and query-free responsiveness for ragged content comes from flexbox.
Named areas: grid at its most readable
Grid template areas deserve their own look because they make layouts self-documenting:
.page {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
}
Each quoted string is one grid row; each word is a named cell. Children then claim their region with grid-area: header and the layout reads like the diagram it represents. Responsive variants simply redefine the areas at a breakpoint, collapsing "sidebar main" into a single column, and the whole page restructures through one property change. Flexbox has no equivalent because one axis cannot describe a map.
Common mistakes worth avoiding
| Mistake | Symptom | Fix |
|---|---|---|
| Building full page layouts in flexbox | Nested wrappers fighting each axis | Grid for the skeleton |
| Using grid for a single toolbar | Track boilerplate for one row | Flexbox for one-axis distribution |
| Forgetting minmax() in grid tracks | Columns overflow on small screens | repeat(auto-fit, minmax(240px, 1fr)) |
| Expecting wrapped flex rows to align | Rows behave independently | Grid when cross-row alignment matters |
The minmax pattern deserves special mention: repeat(auto-fit, minmax(240px, 1fr)) produces responsive columns with zero media queries, and it is the single highest-value grid line most developers learn.
Choosing between flexbox and grid from here
Resolve every future flexbox vs grid question with two checks: how many dimensions does the layout have, and do you know the structure before seeing the content. Two dimensions or known structure means grid; one axis or content-driven sizing means flexbox; most real pages mean both working together. For the wider toolkit around this decision, see the complete guide to developer tools, and when the next layout debate starts, sketch the skeleton in the grid generator first; the right system usually announces itself within one draft.


