Quick Answer

Flexbox lays out items along one axis — a row or a column — and sizes them based on their content. Grid lays out in two dimensions at once, with rows and columns defined by the container. Use Flexbox for components such as navbars, button groups and card internals. Use Grid for page-level structure and anything needing alignment in both directions. They are complementary, and most real pages use Grid for the page and Flexbox inside the pieces.

One Dimension vs Two, and What That Means

The textbook answer is that Flexbox is one-dimensional and Grid is two-dimensional. That is correct but abstract, so here is what it means in practice.

Flexbox lays items along a single axis. You choose row or column, and items flow along it. If they wrap to a second line, each line is sized independently — there is no relationship between an item on line one and an item below it.

Grid defines rows and columns up front, and items are placed into that structure. A cell in column two of row one is aligned with the cell in column two of row three, because the column exists as a thing.

Flexbox with wrapping — lines are independent:
[ item ][ longer item ][ it ]
[ another ][ x ]                    ← no column alignment

Grid — columns exist:
[ item    ][ longer   ][ it   ]
[ another ][ x        ][      ]     ← aligned in both directions

The second framing that decides most real cases: Flexbox is content-first, Grid is layout-first. In Flexbox the items' own sizes shape the layout. In Grid the container declares the structure and the items fit into it.

So if you know the shape you want, that is Grid. If you want things to arrange themselves around their content, that is Flexbox.

What Flexbox Is Best For

Anything arranged along one line, where item sizes should respond to content.

/* Navbar: logo left, links right */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Centring — the most searched CSS question there is */
.center {
  display: flex;
  justify-content: center;   /* main axis */
  align-items: center;       /* cross axis */
}

/* Card footer pinned to the bottom regardless of content height */
.card { display: flex; flex-direction: column; }
.card-body { flex: 1; }      /* takes the leftover space */

That last pattern is genuinely useful and hard with Grid — flex: 1 means "absorb the remaining space", which pushes anything after it to the end.

The flex shorthand is worth knowing properly. flex: 1 is flex-grow: 1; flex-shrink: 1; flex-basis: 0. The flex-basis: 0 is why flex: 1 on several items makes them equal width regardless of content, while flex-grow: 1 alone distributes only the leftover space and leaves items unequal.

Other natural Flexbox uses: button groups, tag lists, form rows, toolbars, and the inside of a card. Note the common thread — these are components, not pages.

What Grid Is Best For

Page structure and anything needing alignment in both directions.

/* Page layout, described declaratively */
.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; }
.sidebar { grid-area: sidebar; }

Named areas make the layout readable at a glance, which no Flexbox equivalent achieves.

The single most useful Grid line is a responsive card layout with no media queries at all:

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

Cards are at least 250px wide, share space equally, and the number per row changes with the viewport automatically. Doing this with Flexbox requires media queries and percentage widths, and the last row never looks right.

fr is Grid's own unit meaning a fraction of the free space — 1fr 2fr splits it one third and two thirds. It handles gaps correctly, unlike percentages.

Other good Grid cases: dashboards, image galleries, forms with aligned labels, and any table-like arrangement that is not tabular data.

Using Both Together

These are not competitors. Real pages use Grid for the page skeleton and Flexbox inside the pieces.

/* Grid positions the major regions */
.layout { display: grid; grid-template-columns: 250px 1fr; }

/* Flexbox arranges what is inside one region */
.header { display: flex; justify-content: space-between; align-items: center; }

/* Grid again for the card collection */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }

/* Flexbox again inside a single card */
.card { display: flex; flex-direction: column; }

The rule that resolves most decisions: ask whether you are arranging things in one direction or two. Then ask whether the container should dictate the structure or the content should. One direction and content-driven means Flexbox; two directions or structure-driven means Grid.

Two properties they share, which is worth knowing because they are frequently attributed to only one:

  • gap works in both, and is far better than margins for spacing — no negative margin hacks and no trailing space on the last item.
  • Alignment propertiesjustify-content, align-items — exist in both, though in Grid they align tracks rather than items along an axis.

Gotchas in Both

Flexbox: items shrink below their content by default. A long word or a wide element can overflow because min-width defaults to auto but flex items get an implicit minimum. The fix is explicit:

.flex-item { min-width: 0; }      /* allows shrinking and text truncation */

This is the reason text-overflow: ellipsis mysteriously fails inside a flex container.

Flexbox: flex-grow alone does not equalise widths. Without flex-basis: 0, items keep their content-based size and only share the leftover space. Use flex: 1.

Grid: 1fr also has a minimum of auto. A grid column can refuse to shrink below its content, causing overflow. Use minmax(0, 1fr) when the content might be wide.

Grid: only direct children are grid items. Grandchildren are laid out by their own parent, which surprises people expecting the whole subtree to participate. Subgrid addresses this and is now widely supported.

Both: the gap property does not collapse. Unlike margins, gaps never merge — usually what you want, but different from the box model behaviour people expect.

Browser support is a non-issue for both in 2026. Neither needs a fallback, and using Flexbox purely for compatibility reasons is no longer a valid argument.

Frequently Asked Questions

Should I learn Flexbox or Grid first? Flexbox, because most components are one-dimensional and you will use it constantly. Learn Grid next for page layouts — the two together cover essentially all modern CSS layout, and neither replaces the other.
Can I use Flexbox and Grid together? Yes, and most real pages do. Grid handles the page skeleton and card collections, while Flexbox arranges the contents of each region and each card. They nest freely.
Which is better for responsive design? Grid, usually, because repeat(auto-fit, minmax(250px, 1fr)) gives a responsive card layout with no media queries at all. Flexbox with wrap works but needs media queries and rarely lays the last row out well.
Why does my flex item overflow its container? Flex items have an implicit minimum size based on content, so they refuse to shrink below it. Set min-width: 0 on the item. This is also why text-overflow: ellipsis often fails inside a flex container.
What is the fr unit in Grid? A fraction of the available free space. 1fr 2fr splits it one third and two thirds, and unlike percentages it accounts for gaps correctly. Use minmax(0, 1fr) when content might otherwise prevent shrinking.