cssgridgenerator All tools
Property guide

CSS Grid vs Flexbox

Use Grid when things must line up in rows and columns, and Flexbox when items flow along one line and should size to their content. Grid is layout first: the container sets the tracks. Flexbox is content first: the items set their size.

Most real pages use both: Grid for the page and card grids, Flexbox inside the pieces. The demo below shows the difference that decides most cases.

See the difference

Same seven items, same minimum width of 140px, same gap. Drag the corner of the box to change its width and watch the last row. Flexbox stretches whatever is left over to fill the line. Grid keeps every column the same width, so the last row lines up with the rows above it.

Flexbox · flex-wrap

OneTwoThreeFourFiveSixSeven

Grid · auto-fill

OneTwoThreeFourFiveSixSeven
.row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.row > * { flex: 1 1 140px; }
.row {
  display: grid;
  grid-template-columns:
    repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}

Side by side

CSS Grid Flexbox
Dimensions Two: rows and columns together. One: a row or a column. Wrapped lines are independent of each other.
Who sets the size The container. You define tracks and items fill them. The items. Each sizes from its content, then the container shares out space.
Alignment across rows Automatic. Column 2 is the same width in every row. None. Each wrapped line is laid out on its own.
Overlapping items Yes, place two items in the same cells. No, not without absolute positioning or negative margins.
Placing items anywhere Yes, by line number or named area, independent of source order. Only reorder along the line with order.
Gap Yes. Yes. Supported in every current browser.
Best for Page layouts, card grids, dashboards, forms with label columns. Navbars, toolbars, button groups, tags, centring one thing.

The real difference: layout in, or content out

"One dimension versus two" is the usual answer, and it is true, but the more useful way to decide is to ask who should decide the sizes.

With Grid, the container decides. You declare the tracks first (240px 1fr, repeat(3, 1fr)) and the content is placed into them. A long word in one card can still widen its column, but the whole column widens with it, so every row stays lined up.

With Flexbox, the items decide. Each one starts from its content size, then the container shares out whatever space is left, or takes it away. A longer label makes a wider button. That is exactly right for a toolbar, and exactly wrong for a grid of cards.

Use Grid for

  • Page layouts. Header, sidebar, content and footer are regions, and grid-template-areas lets you draw them.
  • Card grids. Columns that line up in every row, with no orphaned last row.
  • Dashboards. Panels of different sizes that still share edges.
  • Forms with a label column. grid-template-columns: max-content 1fr lines every label up without fixed widths.
  • Anything that overlaps. Text on an image, a badge on a card.
/* Grid: the page decides the regions,
   content is placed into them. */
.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "nav    main"
    "footer footer";
  min-height: 100dvh;
}

The CSS grid generator draws this kind of layout for you at every breakpoint and writes the media queries.

Use Flexbox for

  • Navbars and toolbars. Items sized to their text, one pushed to the end.
  • Button groups and tags. An unknown number of items of different widths.
  • Centring one thing. display: flex; justify-content: center; align-items: center, though display: grid; place-items: center does the same in one line.
  • Card internals. A footer with a price on the left and a button on the right.
  • Media objects. An avatar next to text that should take the rest of the width.
/* Flexbox: items size to their content,
   the last one is pushed to the end. */
.nav {
  display: flex;
  align-items: center;
  gap: 16px;
}
.nav .account { margin-left: auto; }

The CSS Flexbox generator shows every flex property on a live preview, including the axis swap that trips everyone up.

Use both

This is the normal case, not a compromise. Any grid item can be a flex container, and any flex item can be a grid. A typical page:

.page   { display: grid; grid-template-columns: 240px 1fr; }
.header { display: flex; align-items: center; gap: 16px; }
.cards  { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.card-footer { display: flex; justify-content: space-between; }

When nested content has to line up across separate cards, such as titles, prices and buttons all at the same height, neither nested flex nor nested grid can do it alone. That is what subgrid is for; the CSS subgrid generator builds it.

Common mistakes

Faking a grid with Flexbox. Percentage widths minus the gap, fixed with calc(), adjusted at every breakpoint. If you are writing that, you wanted Grid:

/* Flexbox pretending to be a grid */
.cards > * { width: calc(33.333% - 16px); }

/* What it wanted to be */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

Forcing a toolbar into Grid. Giving every button an equal 1fr column makes short labels waste space and long ones wrap. A row of content-sized items is Flexbox's job.

Reordering visually and forgetting the DOM. Both Grid placement and flex order move things on screen without moving them in the HTML. Keyboard and screen-reader users follow the HTML, so the tab order can jump around.

Forgetting min-width: 0. Flex items and 1fr grid tracks both refuse to shrink below their content by default. In a flex item set min-width: 0; in a grid use minmax(0, 1fr), as covered in the grid-template-columns guide.

Grid layouts to start from

Browse all layout patterns →

Frequently asked questions

What is the difference between CSS Grid and Flexbox?
Grid lays items out in two dimensions at once, rows and columns, with the container deciding the sizes. Flexbox lays items out along one axis, with each item sizing from its content. In short: Grid is layout first, Flexbox is content first.
Is CSS Grid better than Flexbox?
Neither is better; they solve different problems. Grid is the better tool when things must line up in rows and columns, and Flexbox when items in a single row or column should size to their content. Most pages use both.
Can I use Grid and Flexbox together?
Yes, and that is the normal way to build a page. A common split is Grid for the page and for card grids, and Flexbox inside the pieces: the header, a card footer, a row of buttons. Any grid item can be a flex container and the other way round.
Should I use Grid or Flexbox for a navbar?
Flexbox. A navbar is one row of items that should size to their text, with perhaps one pushed to the far end with margin-left: auto. That is exactly what Flexbox does. Grid is only worth it if the navbar has fixed regions, such as a logo, a centred menu and actions.
Should I use Grid or Flexbox for a card layout?
Grid. grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) gives equal columns that line up in every row and reflow without media queries. With Flexbox, the last row stretches or leaves gaps depending on how many cards are left over.
Can Flexbox do two-dimensional layouts?
Not really. flex-wrap makes several lines, but each line is laid out on its own, so items in different lines do not line up in columns. When you need that, you need Grid.
Is Flexbox outdated now that Grid exists?
No. Grid did not replace Flexbox, and both are fully supported in every current browser. Flexbox is still the right tool for most one-dimensional components, which is most components.
Which is faster, Grid or Flexbox?
For normal pages there is no difference worth choosing on. Pick the one that matches the layout; a layout built with the wrong one usually costs more in extra wrappers and CSS than either costs to render.