NC Logo UseToolSuite
CSS & Design

CSS Grid vs Flexbox: Why Your Layout Keeps Breaking

A hands-on comparison of CSS Grid and Flexbox with common layout bugs developers encounter and how to fix them.

Necmeddin Cunedioglu Necmeddin Cunedioglu

Practice what you learn

CSS Gradient Generator

Try it free →

Every few months, I see the same question in dev forums: “Should I use Grid or Flexbox?” And every time, the top answer is some variation of “Grid is for 2D, Flexbox is for 1D.” Which is technically correct but practically useless when you’re staring at a broken layout at 11 PM.

Let me share what I’ve actually learned from building layouts with both — including the mistakes that cost me real debugging time.

The Real Difference (Not the Textbook One)

Forget “1D vs 2D” for a moment. Here’s how I actually think about it:

  • Flexbox is content-first. The content dictates how the layout behaves. Items flex, shrink, and grow based on their content size.
  • Grid is layout-first. You define the structure, then place content into it. The grid doesn’t care how big your content is — it has a plan.

This distinction matters because it determines where bugs come from.

ProblemFlexboxGrid
Items overflow containerCommon — items refuse to shrinkRare — grid cells contain items
Uneven column widthsVery commonEasy to prevent with fr units
Layout shifts on dynamic contentFrequentMinimal
Centering itemsWorks greatWorks great
Responsive without media queriesHarderEasy with auto-fit / minmax()
Browser supportUniversalUniversal (since 2018+)

Bug #1: Flexbox Items Refusing to Shrink

This is probably the most common Flexbox frustration. You set up a nice row, but one item with long text blows out the container:

.container {
    display: flex;
    gap: 16px;
}

.sidebar {
    width: 250px;
}

.content {
    flex: 1;
}

Looks fine until .content has a long URL, a <pre> block, or a wide image. Suddenly, the content overflows and you get a horizontal scrollbar.

Why it happens: Flexbox items have min-width: auto by default, which means they refuse to shrink below their content’s intrinsic width.

The fix:

.content {
    flex: 1;
    min-width: 0; /* Allow the item to shrink below its content size */
}

That single line — min-width: 0 — has saved me more times than I can count. It tells the flex item “yes, you’re allowed to be smaller than your content.”

The Grid equivalent doesn’t have this problem:

.container {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 16px;
}

Grid cells contain their content by default. No overflow, no hacks.

Bug #2: The “Equal Height Cards” Trap

You want a row of cards with equal heights. Seems simple:

.cards {
    display: flex;
    gap: 16px;
}

.card {
    flex: 1;
}

The cards stretch to equal height (Flexbox’s default align-items: stretch handles that). But what about buttons at the bottom of each card?

<div class="card">
    <h3>Short title</h3>
    <p>Brief text.</p>
    <button>Action</button>
</div>

<div class="card">
    <h3>Much Longer Title That Wraps</h3>
    <p>A much longer description that pushes everything down and makes the button misaligned with the other cards.</p>
    <button>Action</button>
</div>

The buttons won’t align across cards because each card’s content pushes the button to a different position.

The Flexbox fix (nested flex):

.card {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.card button {
    margin-top: auto; /* Push button to the bottom */
}

The Grid fix (much simpler):

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

.card {
    display: grid;
    grid-template-rows: auto 1fr auto;
}

With Grid’s subgrid (now supported in all major browsers), you can even align the content across cards — titles line up with titles, descriptions with descriptions, buttons with buttons. That’s something Flexbox simply cannot do.

Bug #3: The flex-grow Misconception

I see this pattern constantly:

.item-1 { flex: 1; }
.item-2 { flex: 2; }
.item-3 { flex: 1; }

Most developers think this means item-2 will be twice as wide as the others. It won’t — at least not exactly. flex-grow distributes remaining space, not total space. If each item has different content widths, the final sizes won’t be the clean ratios you expected.

If you actually want exact ratios, use Grid:

.container {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
}

This gives you exactly 25% / 50% / 25%. No surprises.

Bug #4: Flexbox Wrapping Gone Wrong

.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

This works fine for a tag list. But what about a responsive grid of cards? You’ll often see:

.grid {
    display: flex;
    flex-wrap: wrap;
}

.grid-item {
    flex: 0 0 calc(33.333% - 16px);
    margin: 8px;
}

This “Flexbox grid” pattern was necessary before CSS Grid existed. It’s still everywhere in legacy code. The problems:

  • You have to manually calculate widths accounting for gaps
  • The last row doesn’t align properly if there are fewer items
  • Responsiveness requires manual breakpoint calculations

The modern fix — just use Grid:

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

Three lines. Responsive. No calculations. No last-row alignment issues.

Bug #5: Centering That Almost Works

The famous “center a div” problem. Both Flexbox and Grid solve it, but developers sometimes combine them incorrectly:

/* This doesn't center vertically if the parent has no height */
.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}

Why it doesn’t work: If .parent has no explicit height and its only child is the element you’re trying to center, the parent collapses to the child’s height. Everything looks “centered” horizontally, but vertical centering has no effect.

The fix:

.parent {
    display: flex; /* or display: grid */
    justify-content: center;
    align-items: center;
    min-height: 100vh; /* or 100%, or whatever the container needs */
}

Grid actually has a neat shorthand for this:

.parent {
    display: grid;
    place-items: center;
    min-height: 100vh;
}

Two lines instead of three. Small win, but I like it.

My Decision Framework

After building everything from marketing pages to dashboards to this very site, here’s what I actually use:

Flexbox wins for:

  • Navigation bars
  • Toolbars and button groups
  • Centering single elements
  • Simple horizontal/vertical layouts
  • Spacing items along one axis (e.g., space-between footer links)

Grid wins for:

  • Page layouts (header, sidebar, content, footer)
  • Card grids
  • Form layouts
  • Any time you need items to align across rows AND columns
  • Responsive layouts without media queries

Use both together when:

  • Grid handles the page structure, Flexbox handles the component internals
  • A grid item needs its children laid out in a row

The best layouts I’ve built use Grid for the skeleton and Flexbox for the guts. They’re complementary, not competing.

The Gradient Connection

While we’re talking about CSS, if you’re building components with Grid or Flexbox layouts, consider using gradient backgrounds to add visual depth. A well-placed gradient on a card grid can transform a flat layout into something that feels polished. Check out our CSS Gradient Generator to experiment with gradients you can drop right into your grid layouts.

Stop Fighting Flexbox

Most Flexbox “bugs” aren’t bugs — they’re the result of using a content-first system when you actually need a layout-first one. If you find yourself adding hacks like flex-basis: 0, min-width: 0, and percentage calculations, take a step back and ask: would Grid handle this more naturally?

And if you’re maintaining legacy code with those old Flexbox grid hacks, migrating to CSS Grid is almost always worth the effort. The layout code gets simpler, the bugs go away, and future-you will be grateful.


Related: Learn how to build accessible dark mode layouts in Dark Mode Color Palette Design and ensure your colors meet WCAG standards with our WCAG Color Contrast Guide.

Necmeddin Cunedioglu
Necmeddin Cunedioglu Author

Software developer and the creator of UseToolSuite. I write about the tools and techniques I use daily as a developer — practical guides based on real experience, not theory.