Skip to content
Happy Programming Guide
Start learning
Web Development

CSS Grid vs Flexbox: When to Use Which

Flexbox lays out a line of items; Grid lays out a two-dimensional area. The rule that decides between them, side-by-side examples, and why most pages use both.

Colour-highlighted code on a monitor

Flexbox arranges items along one line and lets them grow, shrink and wrap. Grid divides an area into rows and columns and places items into the cells. The rule that resolves nearly every decision: if you are lining things up in one direction, use Flexbox; if you are designing a layout in two directions at once, use Grid. Most real pages use Grid for the page and Flexbox inside the components.

The deciding question#

Flexbox is one-dimensional. Items go in a row or a column. They can wrap onto more lines, but each line is laid out independently — items on the second line do not align with items on the first.

Grid is two-dimensional. You define rows and columns, and every item sits in that shared structure, so things line up across both axes whether or not they are on the same line.

If you find yourself wanting the second row to line up with the first, you want Grid.

The other way to think about it#

Flexbox works content-out: the items’ sizes drive the layout, and the container distributes leftover space. Grid works layout-in: you draw the structure first and the content fits into it. A navigation bar of links of different widths is content-out. A page with a sidebar and a main column is layout-in.

Three layouts, both ways#

1. A navigation bar#

CSS
/* Flexbox: the natural choice */
.nav {
  display: flex;
  gap: 1.5rem;
  align-items: center;
}
.nav .spacer { margin-left: auto; }   /* pushes what follows to the right */

A row of items, some pushed to the far end, all vertically centred. Grid can do it, but you would be inventing columns for content that does not need them.

2. A card grid#

CSS
/* Grid: as many columns as fit, all cards aligned */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.5rem;
}
CSS
/* Flexbox: works, but the last row spreads or leaves gaps */
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.cards > * { flex: 1 1 260px; }

The Flexbox version stretches the final row’s cards to fill the space, so a lone card on the last line becomes full width. The Grid version keeps every card the same size and aligned with the row above. That difference is the one-dimensional versus two-dimensional distinction made visible.

3. A page shell#

CSS
/* Grid: named areas make the structure readable */
.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  min-height: 100vh;
}
header { grid-area: header; }
aside  { grid-area: sidebar; }
main   { grid-area: main; }
footer { grid-area: footer; }

@media (max-width: 720px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas: "header" "main" "sidebar" "footer";
  }
}

Doing this with Flexbox means nesting a column container inside a row container and fighting to make the heights agree. Grid describes the whole thing in one place, and reordering for mobile is one line.

Where either works#

Centring one thing in a box:

CSS
.centre { display: grid; place-items: center; }
/* or */
.centre { display: flex; justify-content: center; align-items: center; }

Both are fine. Tiebreakers when it genuinely does not matter:

  • Use the one already in use nearby, for consistency.
  • Prefer Grid when you know the structure and Flexbox when you know the content.
  • Prefer Flexbox when items must size themselves — buttons, tags, form controls.

Things Grid does that Flexbox cannot#

  • Overlap items by placing two in the same cell.
  • Span an item across several rows or columns.
  • Align items across rows without knowing how many there are.
  • Define the layout in the parent only, leaving the children untouched.
  • subgrid, which lets a nested grid share the parent’s tracks so card headings line up across cards.

Things Flexbox does more naturally#

  • Distribute leftover space among items of different natural widths.
  • Push one item to the end with margin-left: auto.
  • Wrap a variable number of small items — tags, chips — where alignment between lines does not matter.
  • Reverse direction with a single property.

Both, together#

A typical page: Grid for the shell and for any card or gallery layout; Flexbox inside each header, card footer, button row and form line. They nest without conflict, and using each for what it is good at produces less CSS than forcing either to do everything.

Questions people ask#

Is Grid replacing Flexbox?

No. They solve different problems and were designed to be used together. Neither is newer in any sense that matters; both are fully supported everywhere.

Can I use Grid for a navigation bar?

Yes, and grid-auto-flow: column makes it reasonable. Flexbox is still shorter for content-sized items in a row.

What about floats and tables?

Floats are for wrapping text around images and nothing else. Table layout is for tables of data. Neither should be used for page structure any more.

Does gap work in both?

Yes. gap works in Flexbox and Grid alike and has for years; it replaced the margin hacks in both.

Where to go next#

CSS Grid explained: tracks, areas and auto-fillRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *