Flexbox or grid is the most asked layout question in CSS, and the popular answer, “flexbox for one dimension, grid for two”, is true but stops one sentence short of useful. The deeper difference is who is in charge: flexbox lets content shape the layout, grid lets the layout shape the content. This guide turns that distinction into a decision you can make in five seconds, with our free flexbox generator and grid generator as live sandboxes for both sides.
In this guide
One dimension against two
Flexbox arranges items along one axis, a row or a column, and when items wrap, each new line is its own independent row that knows nothing about the line above. Grid arranges items in rows and columns simultaneously, so cells align in both directions by construction. The wrap behavior is the visible symptom of the difference: a wrapped flexbox row produces a ragged last line of differently-stretched items, while a grid keeps every column aligned through every row. When you find yourself fighting a flexbox wrap with width hacks to force alignment across lines, that is not a bug to fix; that is grid’s job description.
The real difference: who is in charge
Flexbox works content-out: items declare their natural size and flexibility, and the layout emerges from negotiation, growing and shrinking via flex-grow, flex-shrink and flex-basis. The shorthand flex: 1 compresses that negotiation into “ignore your natural size, share the space equally”. Grid works layout-in: the container declares a track structure, columns and rows in fr units and minmax() bounds, and content is placed into it. The five-second decision follows directly: if you know the structure before you know the content, use grid; if the content should determine the structure, use flexbox. A page skeleton is known structure. A row of tag pills of unknown count and width is content in charge.
What flexbox is best at
Flexbox owns the component scale. Navigation bars, where a logo sits left and links sit right with justify-content: space-between doing the pushing. Toolbars, button groups, and input-with-button pairs. Vertical centering of one thing inside another, the problem that consumed a decade of CSS hacks and now takes two declarations. Card internals, where a footer pins to the bottom with margin-top: auto regardless of how much text sits above it. The shared trait: a handful of items, one direction, sizes that should adapt to whatever the content turns out to be. Recreate any of these in the flexbox generator and watch how the alignment keywords move real boxes, which is the fastest cure for the justify-content versus align-items confusion ever invented.
What grid is best at
Grid owns the page scale. The classic header-sidebar-content-footer skeleton is a few lines of grid-template-areas that read like a diagram of themselves. Card galleries are grid’s signature trick: repeat(auto-fill, minmax(250px, 1fr)) produces a responsive gallery that adds and drops columns with the viewport, no media queries involved. Forms with aligned labels, image mosaics with deliberate spans, anything where an element must occupy rows 1 through 3 of column 2, which flexbox cannot express at all. The grid generator makes track definitions tangible: drag the structure, read off the fr and minmax() values, and the syntax stops being abstract.
Using both at once, and the cheat sheet
The question presents as either-or; real pages answer “both, at different levels”. Grid lays out the page, and each grid cell contains components laid out with flexbox: the page skeleton is grid, the nav inside the header is flexbox, the gallery is grid, each card’s internals are flexbox. Nesting them is not a workaround but the intended division of labor.
| You are building | Reach for | Because |
|---|---|---|
| navbar, toolbar, button row | flexbox | one axis, content decides widths |
| page skeleton | grid | known structure, two axes |
| responsive card gallery | grid | auto-fill plus minmax, aligned rows |
| centering one element | either | two lines each; use what the parent already is |
| tags or chips that wrap | flexbox | ragged lines are correct here |
| form with aligned labels | grid | columns align across rows |
Both systems share gap, which replaced the margin gymnastics of older layouts and works identically in each. For sizing the tracks and gaps themselves, the px-rem conversions live in the unit converter, and the wider toolset in the CSS generators pillar.
Frequently asked questions
Is grid replacing flexbox?
No: they were designed in the same era as complements, not competitors. Grid did absorb the page-layout jobs people once forced onto flexbox, which is healthy, but component-level flow layout remains flexbox territory and is not shrinking.
Do I still need media queries with grid?
Fewer: auto-fill with minmax() handles the resize-the-gallery case that once required several breakpoints. Media queries remain for structural changes, like a sidebar moving below content on mobile, where the template itself must change rather than just reflow.
What about browser support?
Both have been universal in every evergreen browser for years, unprefixed, including subgrid in current versions. Support is a closed question for any audience on browsers from this decade; build with whichever fits and spend the worry elsewhere.
Why does justify-content behave differently in grid and flexbox?
Same keyword, different object: in flexbox it distributes items along the main axis, in grid it distributes the tracks themselves within the container, while justify-items moves content within its cell, a property flexbox does not have. Ten minutes of dragging both generators side by side settles the distinction more permanently than memorizing it.