ForgeFrontend — Prepare, Practice, Crack
Secure checkout
Lifetime access
Instant PDF download
Free updates forever

Prepare · Practice · Crack

Flexbox vs CSS Grid

Short answer

Flexbox lays out items along a single axis and lets their content decide the sizes. Grid defines rows and columns up front and places items into that structure. Use Flexbox for a row or column of things, Grid for a two-dimensional layout — and use both together, which is what real pages do.

FlexboxCSS Grid
DimensionsOne axis at a timeTwo axes at once
Sizing modelContent-out — items size themselvesLayout-in — the container defines tracks
Declared on the containerdisplay: flexdisplay: grid
Structure defined byThe order and size of the childrengrid-template-rows / columns
Item placementSequentialSequential or explicitly positioned
Gapsgap (supported)gap (designed for it)
Overlapping itemsAwkwardNative — place two items in one cell
Best atNavbars, toolbars, chips, button rowsPage shells, galleries, dashboards, forms
Alignment propertiesSame ones — justify-*, align-*Same ones, plus per-track control
The distinction is dimensionality — and who decides the sizes.

One axis versus two

The textbook line is that Flexbox is one-dimensional and Grid is two-dimensional, which is correct but rarely explained. It means Flexbox arranges items along a main axis and only aligns them on the cross axis; it never coordinates positions across both at once. Grid establishes a set of rows and columns first, and every item lands in that structure, so items in different rows still line up vertically.

The same six cards, two behaviourscss
1.flex-cards {
2  display: flex;
3  flex-wrap: wrap;
4  gap: 16px;
5}
6/* → items wrap onto new lines, but each line sizes independently.
7     The last row with two items stretches them differently
8     from the row above. Nothing aligns column-wise. */
9
10.grid-cards {
11  display: grid;
12  grid-template-columns: repeat(3, 1fr);
13  gap: 16px;
14}
15/* → three real columns. Every card in column 2 shares an edge,
16     and a short last row leaves its columns empty rather than
17     redistributing the space. */

That last-row behaviour is the clearest practical test. If a partial final row stretching to fill the width looks right, you want Flexbox. If the items should stay in their columns and leave a gap, you want Grid.

Content-out versus layout-in

This is the mental model that makes the choice obvious. In Flexbox, every item starts at its natural content size, and then flex-grow and flex-shrink distribute whatever space is left over or missing. The layout is a consequence of the content. In Grid, you write the track sizes before you know what goes in them, and the items conform.

Who decides the widthcss
1/* Content-out: buttons take the width their labels need */
2.toolbar {
3  display: flex;
4  gap: 8px;
5}
6.toolbar .spacer { flex: 1; }
7/* → a "Delete" button is wider than "OK", and the spacer
8     absorbs everything left over */
9
10/* Layout-in: the sidebar is 240px whatever is inside it */
11.shell {
12  display: grid;
13  grid-template-columns: 240px 1fr;
14  min-height: 100vh;
15}
16/* → the sidebar does not grow because its nav labels got longer,
17     which is usually exactly what a page shell should do */

Stated that way, most layout decisions answer themselves. A row of tags of unknown length is content-out. A dashboard whose panels must line up regardless of what loads into them is layout-in. A form where every label column should share a width is layout-in, which is why Grid quietly replaced a decade of float and table hacks for forms.

The properties, mapped

The alignment properties are shared, which is the part that makes switching between the two cheap once you know it. justify-content, align-items, align-self and gap mean the same things in both — the difference is what axis they act on and what they align.

PropertyIn FlexboxIn Grid
justify-contentDistributes items along the main axisDistributes the whole column track set
align-itemsAligns items on the cross axisAligns items within their row
align-contentDistributes wrapped linesDistributes the whole row track set
gapSpace between items and linesSpace between tracks
align-selfOne item, cross axisOne item, within its cell
justify-selfNot supportedOne item, within its cell
orderReorders items visuallySame, plus explicit placement
flex / frflex: 1 shares leftover space1fr is a share of the free space
Same names, different subjects.

Flexbox in practice

Flexbox owns the small stuff: anything that reads as a row or a column of related items. Navigation bars, button groups, form rows, card footers, chips, media objects with an avatar beside text. The give-away is that you care about spacing and alignment along one direction, and the sizes come from the content.

Three patterns that cover most Flexbox usagecss
1/* 1. Push the last item to the far end */
2.nav { display: flex; align-items: center; gap: 24px; }
3.nav .login { margin-left: auto; }
4/* → logo and links on the left, login on the right,
5     with no wrapper div and no space-between hack */
6
7/* 2. Media object: fixed avatar, text takes the rest */
8.comment { display: flex; gap: 12px; }
9.comment img { flex: 0 0 40px; }
10.comment .body { flex: 1; min-width: 0; }
11/* → min-width: 0 lets long text wrap instead of overflowing */
12
13/* 3. Equal-height columns that size to content */
14.stats { display: flex; gap: 16px; }
15.stats > * { flex: 1 1 0; }
16/* → flex-basis 0 makes all items equal regardless of content;
17     flex: 1 1 auto would size them by content instead */

The difference between flex: 1 1 0 and flex: 1 1 auto is worth knowing precisely, because it is a common interview follow-up. With a basis of zero, the entire width is treated as free space and shared equally, so all items end up the same width. With auto, each item starts at its content width and only the surplus is shared, so a longer label stays wider.

This is 1 of 200+ questions in the Complete Frontend Kit

Get every question with detailed answers, follow-ups and real code — plus coding challenges and a last-minute revision sheet. One-time payment, instant access.

⚡ Get the Complete Frontend Kit → ₹499

Grid in practice

Grid owns the page. A header, sidebar, content and footer arrangement is three lines of CSS. Card galleries that reflow responsively without a single media query are one line. And because tracks exist independently of content, a grid layout does not shift when one panel loads slower than another.

The responsive gallery with no media queriescss
1.gallery {
2  display: grid;
3  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
4  gap: 16px;
5}
6/* → as many columns as fit at 240px minimum; they stretch to
7     share the row. At 1000px that is 4 columns, at 500px it is 2,
8     at 300px it is 1 — with no breakpoints written anywhere. */
9
10/* auto-fill instead of auto-fit changes ONE thing: */
11.gallery-fill {
12  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
13}
14/* → empty tracks are kept. With 2 items in a 1000px container,
15     auto-fit gives 2 stretched cards; auto-fill gives 2 cards
16     at 240px and two empty columns of space. */
Named areas: the layout you can readcss
1.shell {
2  display: grid;
3  grid-template-columns: 240px 1fr;
4  grid-template-rows: auto 1fr auto;
5  grid-template-areas:
6    "header  header"
7    "sidebar main"
8    "footer  footer";
9  min-height: 100vh;
10}
11.shell header { grid-area: header; }
12.shell aside  { grid-area: sidebar; }
13.shell main   { grid-area: main; }
14.shell footer { grid-area: footer; }
15/* → the CSS is a picture of the layout, and rearranging it for
16     mobile means rewriting the three strings inside a media query */

They compose — and real layouts use both

The question is almost never which one for the whole page. Grid handles the outer structure, and each region uses whichever fits. A card grid whose cards are internally Flexbox is the single most common combination on the modern web, and being able to say so with an example is a better answer than picking a side.

Grid outside, Flexbox insidecss
1.gallery {
2  display: grid;
3  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
4  gap: 20px;
5}
6
7.card {
8  display: flex;
9  flex-direction: column;
10  gap: 8px;
11}
12.card .actions { margin-top: auto; }
13/* → every card is the height of the tallest in its row (grid),
14     and every card's buttons sit flush to the bottom (flex),
15     regardless of how much text is above them */

That margin-top: auto is the detail worth stealing. Inside a column flex container it pushes an element to the bottom, which is how you align card footers without knowing the content height — a problem that had no clean solution before Flexbox.

The traps that cost people an afternoon

Both systems have one famous gotcha, and they are the same gotcha: flex and grid items have a minimum size of auto, meaning they refuse to shrink below their content. A long unbroken string or a wide table inside a flex or grid child overflows the container instead of wrapping, and nothing about the CSS looks wrong.

The overflow that makes no sense until you knowcss
1.row { display: flex; }
2.row .content { flex: 1; }
3/* → a long URL or a <pre> block inside .content blows past
4     the container width, ignoring flex: 1 entirely */
5
6.row .content { flex: 1; min-width: 0; }
7/* → fixed: allows the item to shrink below its content size */
8
9.grid-row { display: grid; grid-template-columns: 240px 1fr; }
10.grid-row main { min-width: 0; }
11/* → same fix, same reason. In a grid you can also write
12     grid-template-columns: 240px minmax(0, 1fr); */

Centering, and other one-liners

Centering is the question this topic is most often reduced to, and both do it. Grid does it shorter, which is the only reason to prefer it for that specific job.

The short answerscss
1/* Perfect centering, Grid */
2.box { display: grid; place-items: center; }
3/* → one declaration, both axes */
4
5/* Perfect centering, Flexbox */
6.box { display: flex; justify-content: center; align-items: center; }
7/* → two declarations, identical result */
8
9/* Sticky footer without a fixed height anywhere */
10body { display: grid; grid-template-rows: auto 1fr auto; min-height: 100vh; }
11/* → footer sits at the bottom on short pages and after the
12     content on long ones */

One related question that comes up because of a query people search directly: inline-grid and inline-flex behave exactly like grid and flex on the inside, but the container itself participates as an inline-level box in the surrounding text flow rather than taking the full width of its parent. That is the whole difference.

Can Grid replace Flexbox entirely?

It can produce most layouts, but not always more simply. For a row of items whose widths come from their content, Flexbox is fewer declarations and reads more clearly. Grid also cannot express "items size themselves and share the remainder" as directly as flex: 1 does.

Which has better browser support?

Both are universal in any browser from the last several years — Grid reached broad support in 2017. Subgrid is the only part with a shorter history, and it is now supported across all current browsers. Support is not a deciding factor in 2026.

What is the difference between auto-fit and auto-fill?

They only differ when there are fewer items than fit. auto-fill keeps the empty tracks, so the items stay at their minimum size with space to the right. auto-fit collapses the empty tracks to zero, letting the existing items stretch across the whole row.

Is Grid slower than Flexbox?

Not in any way that matters for typical page layouts — both are implemented natively and are far faster than JavaScript-driven layout. Very large grids with thousands of auto-placed items can cost more to lay out, but at that point virtualising the list is the real answer.

What is subgrid and when do I need it?

It lets a nested grid use its parent's track lines instead of creating its own, so content inside separate cards can align to shared rows. The classic case is a row of cards whose titles, bodies and footers all line up even though each card has a different amount of text.

Frequently asked questions

What is the difference between Flexbox and CSS Grid?
Flexbox arranges items along a single axis and lets each item's content determine its size, distributing the leftover space. Grid defines rows and columns up front and places items into that structure, so items in different rows still align into columns. One is content-out, the other layout-in.
When should I use Flexbox instead of Grid?
When the layout is one row or one column of related items whose sizes should come from their content — navbars, toolbars, button groups, chips, a card's internal stack. If you find yourself thinking about spacing along one direction only, Flexbox is the shorter answer.
When should I use Grid instead of Flexbox?
For anything two-dimensional: page shells with a header, sidebar and footer, card galleries, dashboards, and forms where label columns must align. Also whenever items need to overlap in the same cell, which Grid supports natively and Flexbox does not.
Can I use Flexbox and Grid together?
Yes, and most real layouts do. Grid handles the outer page structure and each region uses whatever fits — a grid gallery whose individual cards are column flex containers is the most common pattern on the modern web.
Can CSS Grid replace Flexbox?
For most layouts it can, but not always more simply. Flexbox expresses "items size themselves and share what is left" more directly, which makes it shorter for rows of content-sized items. They are complementary rather than competing.
How do I center a div with Flexbox and Grid?
With Grid, display: grid and place-items: center — one declaration for both axes. With Flexbox, display: flex plus justify-content: center and align-items: center. Both need a height on the container for vertical centering to be visible.
What is the difference between grid and inline-grid?
The inside is identical; only the container's own behaviour changes. display: grid makes it a block-level box that takes the full available width, while inline-grid makes it an inline-level box that sits in the text flow and shrinks to its content. The same distinction applies to flex and inline-flex.
Why is my flex item overflowing its container?
Because flex and grid items have a minimum size of auto, so they refuse to shrink below their content — a long URL, a wide table or a pre block will push past the container. Add min-width: 0 to the item, or use minmax(0, 1fr) for a grid track.
What does flex: 1 actually mean?
It is shorthand for flex-grow: 1, flex-shrink: 1, flex-basis: 0%. The zero basis is the important part — it means the whole width is treated as free space and shared equally, so items end up the same size. flex: 1 1 auto starts each item at its content size and shares only the surplus.
What is the difference between auto-fit and auto-fill in CSS Grid?
They behave identically when the items fill the row. When there are fewer items, auto-fill keeps the empty tracks so items stay at their minimum width, and auto-fit collapses those tracks to zero so the existing items stretch to fill the row.
Does Flexbox support gap?
Yes, in every current browser. Before that landed, spacing between flex items meant negative margins on the container and margins on each child. If you see that pattern in an older codebase, gap is the modern replacement.
What is subgrid in CSS Grid?
A track value that makes a nested grid inherit its parent's row or column lines instead of defining new ones, so content inside separate children can align to shared tracks. It solves the case where every card in a row should have its title, body and footer aligned despite different text lengths.

This is 1 of 200+ questions in the Complete Frontend Kit

Get every question with detailed answers, follow-ups and real code — plus coding challenges and a last-minute revision sheet. One-time payment, instant access.

⚡ Get the Complete Frontend Kit → ₹499
Written by Arun Karthikeyan · Last updated

Full kit

Complete Frontend Kit · ₹499

Get it →