Toolmingo
Guides11 min read

CSS Grid vs Flexbox: When to Use Each (2025 Guide)

A complete comparison of CSS Grid and Flexbox — covering use cases, syntax, browser support, and practical examples to help you choose the right layout tool.

CSS Grid and Flexbox are both powerful layout systems built into the browser — but they solve different problems. Flexbox is one-dimensional (row or column). Grid is two-dimensional (rows and columns simultaneously). This guide shows exactly when to use each, with side-by-side examples.

At a glance

Flexbox CSS Grid
Dimensions 1D — row or column 2D — rows and columns
Direction Main axis + cross axis Explicit rows + columns
Item placement Flow-based (auto) Explicit or auto
Alignment justify-content, align-items justify-items, align-items, place-items
Gap gap gap / column-gap / row-gap
Browser support 98%+ 97%+
Best for Navigation bars, card rows, buttons, form controls Page layouts, dashboards, image galleries, complex grids
Item sizing flex-grow, flex-shrink, flex-basis fr, minmax(), auto-fill, auto-fit
Overlapping items Not supported Supported (z-index + grid placement)
Spec CSS Flexible Box Module Level 1 CSS Grid Layout Module Level 1 + 2

1. What Flexbox does

Flexbox aligns items along one axis at a time — either a row or a column. Items grow and shrink to fill available space.

.container {
  display: flex;
  flex-direction: row;        /* or column */
  justify-content: space-between; /* main axis */
  align-items: center;            /* cross axis */
  gap: 1rem;
}

Flex item properties

.item {
  flex-grow: 1;    /* take remaining space */
  flex-shrink: 0;  /* don't shrink below flex-basis */
  flex-basis: 200px; /* starting size */

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

Common Flexbox patterns

Centered element:

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

Equal-width columns:

.nav {
  display: flex;
}
.nav-item {
  flex: 1;
}

Push last item to end:

.toolbar {
  display: flex;
  align-items: center;
}
.toolbar .spacer {
  flex: 1;
}
/* or: margin-left: auto on last item */

Wrap cards:

.card-list {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.card {
  flex: 1 1 300px; /* grow, shrink, min-width 300px */
}

2. What CSS Grid does

Grid creates a two-dimensional coordinate system. You define rows and columns explicitly, then place items anywhere in that system.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto;
  gap: 1.5rem;
}

Grid item placement

/* Explicit placement */
.sidebar {
  grid-column: 1 / 2;
  grid-row: 1 / 3;
}

/* Span shorthand */
.feature-card {
  grid-column: span 2;
}

/* Named areas */
.container {
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "footer footer footer";
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Responsive grid without media queries

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

auto-fill creates as many columns as fit. minmax(250px, 1fr) ensures each column is at least 250px wide and grows to fill space.


3. Flexbox vs Grid — real examples side by side

Navigation bar

Flexbox (perfect fit — 1D row):

.nav {
  display: flex;
  align-items: center;
  gap: 2rem;
  padding: 0 1rem;
}
.nav-logo { margin-right: auto; } /* pushes links to right */

Grid (overcomplicated for this):

/* Works but overkill */
.nav {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
}

→ Use Flexbox for nav bars.


Page layout

Grid (perfect fit — 2D layout):

.page {
  display: grid;
  grid-template-columns: 260px 1fr;
  grid-template-rows: 60px 1fr 50px;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer";
  min-height: 100vh;
}

Flexbox (requires nesting):

<!-- Needs multiple nested flex containers -->
<div class="flex-column">
  <header>...</header>
  <div class="flex-row">
    <aside>...</aside>
    <main>...</main>
  </div>
  <footer>...</footer>
</div>

→ Use Grid for page layouts.


Card grid

Grid (clean auto-placement):

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

Flexbox (needs flex-wrap, less control):

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.card {
  flex: 1 1 280px;
  max-width: calc(33.333% - 1rem); /* magic numbers */
}

→ Use Grid for card grids.


Button group / form controls

Flexbox (natural fit):

.button-group {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.form-row {
  display: flex;
  gap: 1rem;
  align-items: flex-end;
}

→ Use Flexbox for inline controls.


4. Alignment comparison

Both Flexbox and Grid support justify-* and align-* properties, but they work differently.

Property Flexbox Grid
justify-content Distributes items on main axis Distributes columns on inline axis
align-content Distributes rows when wrapping Distributes rows on block axis
justify-items Not applicable Aligns all items horizontally in cell
align-items Aligns items on cross axis Aligns all items vertically in cell
justify-self Not applicable Aligns single item horizontally
align-self Aligns single item on cross axis Aligns single item vertically
place-items Not applicable align-items + justify-items shorthand
place-self Not applicable align-self + justify-self shorthand
place-content Shorthand for both Shorthand for both

Grid centering — simplest way:

.parent {
  display: grid;
  place-items: center; /* centers both axes */
}

Flexbox centering:

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

5. Sizing units

Flexbox: flex shorthand

/* flex: grow shrink basis */
.item { flex: 1 1 auto; }  /* default */
.item { flex: 1; }         /* flex-grow:1, flex-shrink:1, flex-basis:0 */
.item { flex: 0 0 200px; } /* fixed 200px, no grow/shrink */
.item { flex: 2; }         /* takes twice as much space as flex:1 siblings */

Grid: fr units and minmax

/* fr = fraction of remaining space */
.grid {
  grid-template-columns: 1fr 2fr 1fr; /* 25% 50% 25% */
}

/* minmax: at least 200px, grow to fill */
.grid {
  grid-template-columns: repeat(3, minmax(200px, 1fr));
}

/* fixed + flexible */
.layout {
  grid-template-columns: 260px 1fr; /* sidebar + content */
}

/* responsive without media queries */
.gallery {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

auto-fill vs auto-fit:

  • auto-fill — creates empty columns even if no items fill them
  • auto-fit — collapses empty columns, items expand to fill space
  • Use auto-fit when you want fewer items to stretch across full width

6. Nesting Grid and Flexbox

They work great together. A common pattern: Grid for macro layout, Flexbox for micro layout inside grid cells.

/* Grid handles overall page structure */
.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "footer";
  grid-template-rows: auto 1fr auto;
}

/* Flexbox handles items inside header */
.header {
  grid-area: header;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2rem;
}

/* Flexbox handles card content layout */
.card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.card-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: auto; /* push actions to bottom */
}

7. Subgrid (CSS Grid Level 2)

Subgrid lets nested elements align to the parent grid's tracks — eliminating the need for magic numbers to align columns across cards.

/* Parent grid */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

/* Each card spans 1 column but creates its own 3-row subgrid */
.card {
  display: grid;
  grid-row: span 3;
  grid-template-rows: subgrid; /* aligns to parent row tracks */
}

/* Now all card titles, descriptions, buttons align across cards */
.card-title       { /* row 1 */ }
.card-description { /* row 2 */ }
.card-actions     { /* row 3 */ }

Browser support: Chrome 117+, Firefox 71+, Safari 16+. Use @supports for fallback.


8. Browser support and legacy fallbacks

Feature Chrome Firefox Safari Edge
Flexbox 29+ (2013) 28+ (2014) 9+ (2015) 12+
CSS Grid 57+ (2017) 52+ (2017) 10.1+ (2017) 16+
Grid gap 66+ 61+ 12+ 16+
subgrid 117+ 71+ 16+ 117+
auto-fit/auto-fill 57+ 52+ 10.1+ 16+
place-items 59+ 45+ 11+ 79+

All modern production browsers fully support both Flexbox and Grid. IE11 has partial Grid support (old spec) but IE11 is below 0.5% market share — ignore it in 2025.


9. Performance

Both layout systems are GPU-accelerated by the browser. Performance differences are negligible for typical UIs.

Practical tips:

  • Avoid deeply nested flex/grid containers (increases layout calculations)
  • will-change: transform on animated items, not on containers
  • contain: layout on components that don't affect siblings
  • Prefer transform + opacity for animations — not width/height/margin

10. Decision guide

Need to center a single item?
  → display: grid; place-items: center;

1D layout (all in a row or all in a column)?
  → Flexbox

2D layout (rows AND columns matter)?
  → Grid

Navigation bar / toolbar?
  → Flexbox

Page-level layout (header/sidebar/main/footer)?
  → Grid

Card grid with equal columns?
  → Grid (auto-fill/auto-fit)

Card grid where column count varies by item?
  → Flexbox with flex-wrap

Items must overlap?
  → Grid (z-index + explicit placement)

Form controls / button groups?
  → Flexbox

Dashboard with panels?
  → Grid (named areas)

Complex responsive layout without media queries?
  → Grid (auto-fit + minmax)

Rule of thumb: If you're thinking about the container's overall structure, reach for Grid. If you're thinking about how items flow relative to each other, reach for Flexbox.


11. Quick reference: Flexbox properties

Property Values Purpose
display flex / inline-flex Enable Flexbox
flex-direction row row-reverse column column-reverse Main axis direction
flex-wrap nowrap wrap wrap-reverse Whether items wrap
justify-content flex-start flex-end center space-between space-around space-evenly Main axis alignment
align-items stretch flex-start flex-end center baseline Cross axis alignment
align-content Same as justify-content Multi-line cross axis
gap length Space between items
flex-grow number (default 0) Grow factor
flex-shrink number (default 1) Shrink factor
flex-basis length / auto Initial size
align-self Same as align-items Override per item
order integer Visual reorder

12. Quick reference: CSS Grid properties

Property Values Purpose
display grid / inline-grid Enable Grid
grid-template-columns track sizes Define columns
grid-template-rows track sizes Define rows
grid-template-areas area names Named layout
grid-auto-columns track size Implicit column size
grid-auto-rows track size Implicit row size
grid-auto-flow row column dense Auto-placement direction
gap / row-gap / column-gap length Gutters
grid-column start / end Item column placement
grid-row start / end Item row placement
grid-area name or row-start / col-start / row-end / col-end Item placement
justify-items start end center stretch Inline alignment of all cells
align-items start end center stretch Block alignment of all cells
place-items align / justify Both axes shorthand
justify-content start end center stretch space-around space-between space-evenly Distribute columns
align-content Same Distribute rows

13. Common mistakes

Mistake Problem Fix
Using Flexbox for a 2D page layout Requires deeply nested containers Switch to Grid for macro layout
Using Grid for a simple nav bar Overcomplicated, fragile column sizing Use Flexbox with margin-left: auto
Forgetting min-width: 0 on flex items Text or images overflow container Add min-width: 0 (or overflow: hidden) to flex children
auto-fill when you want items to stretch Empty columns appear Use auto-fit instead
Nesting flex inside flex too deeply Brittle, hard to maintain Extract inner components to Grid
Hardcoding column widths in Flexbox Breaks on different viewports Use flex: 1 1 minmax(...) or switch to Grid
Using width: 50% inside a flex item Ignores flex model Use flex-basis or flex: 0 0 50%
Mixing align-items vs justify-content up Items appear in wrong place Remember: justify = main axis, align = cross axis

14. CSS Grid vs Flexbox vs other layout methods

Layout method Dimensions Best for Browser support
Flexbox 1D Component-level layout, nav, toolbars 98%+
CSS Grid 2D Page layout, dashboards, card grids 97%+
Float 1D Legacy only (avoid in new code) 100%
CSS Multi-column 1D Magazine-style text columns 95%+
CSS Subgrid 2D Cross-card alignment Chrome 117+, FF 71+, Safari 16+
Table layout 2D Tabular data (use <table>) 100%
Positioned layout Overlays, tooltips, modals 100%

Frequently asked questions

Should I learn Flexbox or Grid first? Learn Flexbox first — it's simpler and solves most component-level problems. Then add Grid for page layouts and complex 2D arrangements. Most real projects use both.

Can I use Grid for everything? Yes, but you'll write more verbose CSS for simple 1D cases. Use the right tool for each job.

Does CSS Grid replace Flexbox? No. They complement each other. Grid excels at placing elements in two dimensions. Flexbox excels at distributing space along one axis. Most modern projects use both on the same page.

Which is faster — Grid or Flexbox? Performance is effectively identical for typical UI. Browser layout engines handle both efficiently. Don't choose based on performance.

How do I make a Flexbox layout responsive? Use flex-wrap: wrap and flex: 1 1 <min-width> on items. For Grid, use repeat(auto-fit, minmax(250px, 1fr)) — no media queries needed.

Is CSS Grid supported in all browsers? Yes, in all modern browsers (Chrome, Firefox, Safari, Edge). IE11 has partial support with an older syntax, but IE11 is below 0.5% market share in 2025 — not worth worrying about.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools