MeshWorld MeshWorld.
CSS Web Dev Frontend How-To Developer Tools 7 min read

CSS Grid vs Flexbox: When to Use Which

Scarlett
By Scarlett

I’ve had this conversation probably fifty times. Someone’s building a layout, they reach for flexbox because it’s what they know, and two hours later they have a flex-wrap nightmare that kind of works on desktop and falls apart on mobile. Or they use grid for a simple button row and wonder why alignment feels wrong. The tool matters. Here’s how to pick the right one.

:::note[TL;DR]

  • Flexbox is for one-dimensional layouts — a row or a column, not both at once
  • Grid is for two-dimensional layouts — rows and columns simultaneously
  • Nav bars, button groups, card rows → Flexbox. Page layouts, complex grids, asymmetric designs → Grid
  • You can and should nest them: Grid for the page skeleton, Flexbox inside each section
  • Both have full browser support in 2026 — no compatibility excuses :::

What’s the core mental model difference?

Flexbox thinks in one axis at a time. You pick a direction — flex-direction: row or column — and it lays items along that axis. Wrapping happens, but you don’t control the second axis precisely. Flexbox distributes space. Grid controls space.

Grid thinks in two dimensions simultaneously. You define explicit rows and columns, and you place items into that coordinate system. Grid doesn’t care which axis is “primary” — both matter equally.

The practical consequence: if you’re looking at your design and thinking “these items should line up across rows and columns,” that’s Grid. If you’re thinking “these items should flow along a line,” that’s Flexbox.


When does Flexbox win?

Navigation bars. A nav is a row of links. Flexbox with justify-content: space-between or flex-end handles this perfectly. Adding Grid here is unnecessary complexity.

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

Button groups. A cluster of buttons that should wrap on small screens. Flexbox with flex-wrap: wrap is exactly right.

Card rows where you don’t need strict column alignment. If you have a row of cards and you don’t care that they’re the same height or that their content aligns across cards, Flexbox is simpler. Add flex: 1 to let them share space evenly.

Centering a single item. Still the clearest solution:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

Sidebar + main content pairs. A two-column layout where one column is fixed and one grows — this is one-dimensional (a row), so Flexbox handles it cleanly.

.layout {
  display: flex;
  gap: 2rem;
}
.sidebar { flex: 0 0 240px; }
.main { flex: 1; }

When does Grid win?

Page-level layouts. Header, sidebar, main content, footer — that’s a two-dimensional structure. Grid makes this explicit and maintainable:

.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;
}

Magazine-style asymmetric grids. When different items span different numbers of columns or rows, Grid’s grid-column and grid-row spanning is the only sane approach. Flexbox can’t do this without hacks.

.featured-card {
  grid-column: span 2;
  grid-row: span 2;
}

Image galleries where alignment across rows matters. If you want every thumbnail in the same position regardless of image content, you need Grid. Flexbox wrapping doesn’t guarantee that items in row 2 align with items in row 1.

Form layouts. Label + input pairs where the labels should all align to the same column edge. Grid with grid-template-columns: max-content 1fr is clean and correct.

.form {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.75rem 1rem;
  align-items: center;
}

auto-fill and auto-fit responsive grids. Responsive card grids without media queries:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

This is one of Grid’s best features — it creates as many columns as fit, at a minimum width of 280px. No media queries needed.


Quick decision table

SituationUse
Items flow in one directionFlexbox
Items need to align in rows AND columnsGrid
Nav bar or toolbarFlexbox
Full page layoutGrid
Button groupFlexbox
Card gallery with consistent rowsGrid
Centering a single elementFlexbox
Asymmetric multi-column layoutGrid
Items should wrap and distribute spaceFlexbox
Form with label/input pairsGrid
Sidebar + main contentEither (both work)

What are the most common mistakes?

Using Flexbox for page layout and fighting wrapping. When you have a header, sidebar, content, and footer, that’s not a flex container — it’s a grid. People force Flexbox to do two-dimensional work and end up with media query spaghetti.

Using Grid for a button row. Overkill. Flexbox gap and justify-content is two lines. Grid adds four lines and requires you to think about column definitions for something that’s just a line of buttons.

Forgetting that Flexbox children ignore width unless you set flex-shrink: 0. A common bug: you set a sidebar to width: 240px, it shrinks anyway, you add min-width: 240px, it still fights. Use flex: 0 0 240px — shorthand for flex-grow: 0; flex-shrink: 0; flex-basis: 240px. That’s a fixed-width flex item.

Using flex: 1 on everything. This distributes remaining space equally, which sounds right, but it also means items shrink below their content. Use flex: 1 1 auto or set min-width: 0 on the item to handle text overflow correctly.

Nesting Grid inside Grid when Flexbox inside Grid is cleaner. Your page skeleton is Grid. Each section inside it is probably a simple row or column — that’s Flexbox. You don’t need Grid all the way down.


What about browser support?

In 2026, both are fully supported everywhere that matters. Grid has been baseline-compatible since 2017. Subgrid (for aligning nested grid items to the parent grid’s tracks) reached baseline status in 2023 and is now safe to use. The only real caveat: masonry layout in CSS Grid is still behind a flag in most browsers as of early 2026 — use JavaScript masonry libraries if you need it.


Summary

  • Flexbox = one axis, space distribution, flow
  • Grid = two axes, placement control, structure
  • The right answer is usually both: Grid for the outer structure, Flexbox inside each region
  • auto-fill + minmax() in Grid is the cleanest way to write responsive card layouts
  • The most common mistake is trying to stretch Flexbox into two-dimensional work it was never designed for

FAQ

Can I use Grid and Flexbox together?

Yes, and you should. They’re not competing tools — they solve different problems. A page layout in Grid with Flexbox inside each section is the standard pattern. A nav inside a Grid header cell is perfectly normal. There’s no performance difference worth thinking about.

What replaced the old float-based layouts?

Flexbox and Grid both did. Floats (float: left, float: right) were used for layout because there was nothing better before 2017. They were never designed for layout — they were designed for text wrapping around images. Don’t use floats for layout in 2026. The only legitimate use is wrapping text around a floated image.

Is CSS subgrid useful?

Yes, for a specific problem: aligning nested items to the outer grid’s tracks. Classic use case — a card grid where each card has a title, body, and button, and you want all the buttons to sit at the same vertical position regardless of content length. Without subgrid, you’d need JavaScript. With grid-template-rows: subgrid, the card’s rows align to the parent grid. Now safe to use in production.