DevBolt
·9 min read

CSS Flexbox vs Grid: When to Use Each Layout System

CSSLayoutFrontendComparison

CSS Flexbox and Grid are both layout systems, but they solve different problems. Flexbox handles one-dimensional layouts (rows or columns). Grid handles two-dimensional layouts (rows and columns at the same time). This guide covers when to use each, how they differ, and how to combine them.

Quick Comparison

FeatureFlexboxGrid
Layout modelOne-dimensional (row or column)Two-dimensional (rows and columns)
Content vs layoutContent-first (items size themselves)Layout-first (grid defines the structure)
AlignmentMain axis + cross axisRow axis + column axis + area placement
Gapsgaprow-gap, column-gap, gap
Item placementSource order (or order)Explicit line numbers, named areas, span
Wrappingflex-wrap (new rows lose alignment)Implicit rows/columns maintain grid tracks
Browser support98%+ (since 2015)97%+ (since 2017)
Best forNavbars, button groups, centeringPage layouts, dashboards, card grids

Flexbox: One Direction at a Time

Flexbox lays out items along a single axis. You choose the direction with flex-direction — either row (horizontal) or column (vertical). Items distribute themselves along that axis based on their content size and flex properties.

Classic Navbar

CSS
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 1.5rem;
}

/* Items naturally size to their content
   and distribute along the main axis */

Centering (the reason Flexbox exists)

CSS
.center-both {
  display: flex;
  justify-content: center;  /* horizontal */
  align-items: center;      /* vertical */
  min-height: 100vh;
}

Key Flex Properties

CSS
.item {
  flex-grow: 1;    /* Take up available space */
  flex-shrink: 0;  /* Don't shrink below basis */
  flex-basis: 200px; /* Starting size */

  /* Shorthand: */
  flex: 1 0 200px;
}

Grid: Rows and Columns Together

CSS Grid defines a two-dimensional layout on the container. You declare rows and columns, then place items into the resulting cells. The grid structure exists independently of the content — items slot into it.

Responsive Card Grid

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

/* Cards automatically wrap to new rows
   and stay aligned in a proper grid */

Dashboard Layout with Named Areas

CSS
.dashboard {
  display: grid;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Spanning Rows and Columns

CSS
.featured {
  grid-column: span 2;  /* Take up 2 columns */
  grid-row: span 2;     /* Take up 2 rows */
}

.sidebar {
  grid-column: 3;       /* Place in column 3 */
  grid-row: 1 / -1;     /* Span all rows */
}

The Wrapping Problem

This is where the real difference shows. When Flexbox items wrap with flex-wrap: wrap, each row is independent — items in row 2 don't align with items in row 1. Grid maintains column alignment across all rows because the tracks are defined on the container, not the items.

Flexbox wrapping — columns DON'T align
.flex-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.flex-cards > * {
  flex: 1 1 300px;
  /* If 2 items land in the last row, they stretch
     to fill the space — NOT aligned to the grid above */
}
Grid wrapping — columns DO align
.grid-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
  /* Items always align to the same column tracks,
     regardless of how many are in the last row */
}

When to Use Flexbox

  • Navigation bars — horizontal lists of links with flexible spacing.
  • Button groups and toolbars — items that need even spacing in a single row.
  • Centering content — the fastest way to center anything horizontally and vertically.
  • Content-driven layouts — when items should size based on their content, not a predefined grid.
  • Reordering within a single axis — the order property makes it easy to rearrange items without changing HTML.

When to Use Grid

  • Page layouts — header, sidebar, main, footer arrangements.
  • Card grids — when items should maintain column alignment across rows.
  • Dashboards — complex layouts with items spanning multiple rows or columns.
  • Form layouts — label/input pairs that need consistent column alignment.
  • Overlapping elements — Grid allows items to occupy the same cell, useful for image overlays and stacking without position: absolute.

Using Them Together

The best layouts combine both. Use Grid for the overall page structure and Flexbox for components within grid cells.

CSS
/* Grid for the page layout */
.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* Flexbox for the header inside the grid */
.header {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

/* Grid for the card section inside main */
.card-section {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1rem;
}

/* Flexbox inside each card */
.card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

Deploying CSS-heavy applications?

Netlify deploys your frontend instantly with automatic HTTPS, CDN, and preview deploys for every pull request — perfect for testing responsive layouts.

Common Mistakes

  • Using Flexbox for card grids. Wrapped Flexbox items don't maintain column alignment. Switch to grid with auto-fill/minmax().
  • Using Grid for simple centering. While place-items: center works, display: flex with justify-content and align-items is more intuitive for single-element centering.
  • Forgetting min-width: 0 in Flexbox. Flex items default to min-width: auto, which prevents them from shrinking below their content size. This causes overflow with long text or code blocks.
  • Over-specifying Grid tracks. Use auto-fill and minmax() instead of hardcoded column counts. Let the browser handle responsiveness.

The Verdict

They're not competing. Flexbox is for distributing items in a single direction. Grid is for defining two-dimensional layouts. Use Flexbox inside Grid cells. Use Grid for overall page structure. The question isn't “which one” — it's “which one here.”

Try It Yourself

Build Flexbox layouts visually with our CSS Flexbox Generator, create Grid layouts with the CSS Grid Generator, or convert your CSS to Tailwind utility classes with the CSS to Tailwind Converter.