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

Flexbox and Grid are not competing layout systems — they solve different problems. This guide shows you exactly when to reach for each, with side-by-side code examples for every common layout pattern.

The Core Difference: One vs Two Dimensions

The fundamental difference between Flexbox and Grid comes down to dimensions. Flexbox is one-dimensional: it lays out items along a single axis (either a row or a column). Grid is two-dimensional: it controls both rows and columns at the same time.

This is not a quality judgment. A navigation bar is inherently one-dimensional — items flow in a row. A dashboard layout is inherently two-dimensional — content needs to align both horizontally and vertically. The layout dictates the tool.

The Decision Rule

If your layout works as a line of items (even if that line wraps), use Flexbox. If your layout needs items to align in both rows and columns simultaneously, use Grid. If you are unsure, start with Flexbox — you can always refactor to Grid if alignment across both axes becomes a problem.

Flexbox Essentials

Flexbox works with two types of elements: the flex container (the parent with display: flex) and the flex items (the direct children). The container controls the overall flow, and items can control their own sizing and alignment within that flow.

css — Flexbox container properties
.container {
  display: flex;

  /* Direction: row (default), row-reverse, column, column-reverse */
  flex-direction: row;

  /* Wrapping: nowrap (default), wrap, wrap-reverse */
  flex-wrap: wrap;

  /* Main axis alignment */
  justify-content: flex-start;   /* start (default) */
  justify-content: center;       /* center items */
  justify-content: space-between;/* equal space between items */
  justify-content: space-around; /* equal space around items */
  justify-content: space-evenly; /* truly equal spacing */

  /* Cross axis alignment */
  align-items: stretch;          /* fill height (default) */
  align-items: flex-start;       /* top align */
  align-items: center;           /* center vertically */
  align-items: flex-end;         /* bottom align */
  align-items: baseline;         /* align by text baseline */

  /* Gap between items */
  gap: 16px;                     /* row and column gap */
  row-gap: 16px;                 /* only row gap */
  column-gap: 24px;              /* only column gap */
}
css — Flexbox item properties
.item {
  /* How much the item grows relative to siblings */
  flex-grow: 1;     /* take up available space */
  flex-grow: 0;     /* do not grow (default) */

  /* How much the item shrinks when space is tight */
  flex-shrink: 1;   /* allow shrinking (default) */
  flex-shrink: 0;   /* do not shrink */

  /* Base size before growing/shrinking */
  flex-basis: auto;  /* use width/height (default) */
  flex-basis: 200px; /* start at 200px */
  flex-basis: 0;     /* ignore content size, distribute space evenly */

  /* Shorthand: grow shrink basis */
  flex: 1;           /* flex: 1 1 0% — grow, shrink, ignore content size */
  flex: 0 0 auto;    /* no grow, no shrink, use content size */

  /* Override container's align-items for this item */
  align-self: center;

  /* Change visual order without changing DOM order */
  order: -1;         /* move to the front */
}

You can experiment with all of these properties interactively in the Flexbox Playground — adjust values and see the result in real time without writing code.

Grid Essentials

Grid introduces a coordinate system. You define rows and columns on the container, and items can be placed into specific cells or allowed to flow automatically.

css — Grid container properties
.container {
  display: grid;

  /* Define columns */
  grid-template-columns: 200px 1fr 200px;         /* fixed-flexible-fixed */
  grid-template-columns: repeat(3, 1fr);           /* three equal columns */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* responsive */

  /* Define rows */
  grid-template-rows: auto 1fr auto;               /* header-content-footer */
  grid-auto-rows: minmax(100px, auto);             /* implicit row sizing */

  /* Named areas (visual layout) */
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";

  /* Gaps */
  gap: 16px;
  row-gap: 16px;
  column-gap: 24px;

  /* Alignment of all items within their cells */
  justify-items: stretch;    /* fill cell width (default) */
  align-items: stretch;      /* fill cell height (default) */

  /* Alignment of the entire grid within the container */
  justify-content: center;   /* center grid horizontally */
  align-content: center;     /* center grid vertically */
}
css — Grid item placement
.item {
  /* Place by line numbers */
  grid-column: 1 / 3;         /* span columns 1 to 3 */
  grid-row: 2 / 4;            /* span rows 2 to 4 */

  /* Place by named area */
  grid-area: header;           /* matches grid-template-areas name */

  /* Span multiple cells */
  grid-column: span 2;         /* span 2 columns from auto position */
  grid-row: span 3;            /* span 3 rows */

  /* Self-alignment within the cell */
  justify-self: center;        /* center horizontally in cell */
  align-self: end;             /* align to bottom of cell */
}

The CSS Grid Playground lets you define grid tracks, place items, and see the result immediately. It is the fastest way to prototype grid layouts before writing the final CSS.

Side-by-Side Comparison

Feature Flexbox Grid
Layout dimension One-dimensional (row OR column) Two-dimensional (row AND column)
Content vs layout Content-driven (items size themselves) Layout-driven (grid defines the structure)
Item placement Items flow in order, wrapping when needed Items can be placed in any cell explicitly
Overlap Not possible without position hacks Items can overlap by occupying the same cells
Named areas Not available grid-template-areas for visual layout definition
Subgrid Not available Child grids inherit parent track sizes
Implicit tracks Items wrap to new lines automatically New rows/columns created automatically for overflow
Gap support Yes (gap, row-gap, column-gap) Yes (gap, row-gap, column-gap)
Browser support 97%+ (since 2013) 97%+ (since 2017, subgrid since 2023)

When to Use Flexbox

Flexbox is the right choice when items flow along a single axis and their sizes should be driven by their content.

Navigation Bars

css — Horizontal navigation
.navbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 24px;
  height: 64px;
}

.navbar-logo {
  margin-right: auto; /* pushes everything else to the right */
}

.navbar-link {
  white-space: nowrap;
}

The margin-right: auto trick on the logo pushes all nav links to the right side. This is a Flexbox-only pattern that is cleaner than any Grid alternative.

Centering Content

css — Perfect centering
/* The simplest way to center anything */
.center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

Form Layouts

css — Input with button
.search-form {
  display: flex;
  gap: 8px;
}

.search-input {
  flex: 1; /* takes all available space */
  min-width: 0; /* allows shrinking below content size */
}

.search-button {
  flex-shrink: 0; /* never shrink the button */
}

Other Flexbox Use Cases

When to Use Grid

Grid is the right choice when items need to align in both directions or when you want the layout structure to be independent of the content.

Card Grids

css — Responsive card grid
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
}

/* Each card fills its cell — no extra sizing needed */
.card {
  background: var(--surface);
  border-radius: 12px;
  padding: 24px;
}

This single CSS rule creates a responsive grid that adapts from 1 column on mobile to 2, 3, or 4 columns on wider screens without any media queries. Each card is the same width within its row.

Page Layout (Holy Grail)

css — Classic page layout with named areas
.page {
  display: grid;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  grid-template-columns: 240px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  gap: 0;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }

/* Responsive: collapse to single column */
@media (max-width: 768px) {
  .page {
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "aside"
      "footer";
    grid-template-columns: 1fr;
  }
}

Named grid areas make the layout immediately readable. The visual ASCII-art pattern in grid-template-areas maps directly to the page structure. Rearranging for mobile takes one media query.

Dashboard Layout

css — Dashboard with spanning widgets
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(200px, auto);
  gap: 16px;
}

.widget-large {
  grid-column: span 2;
  grid-row: span 2;
}

.widget-wide {
  grid-column: span 2;
}

.widget-tall {
  grid-row: span 2;
}

Other Grid Use Cases

When converting your Grid layouts to utility-class frameworks, the CSS to Tailwind Converter translates grid-template-columns, gap, and placement properties to their Tailwind equivalents.

Build Layouts Visually, Copy the CSS

QTool has free Flexbox and Grid playgrounds. Drag, adjust, and export production-ready CSS without writing a line of code.

Flexbox Playground Grid Playground

Combining Flexbox and Grid

The most effective layouts use both. Grid handles the macro layout (page sections), and Flexbox handles the micro layout (content inside each section).

css — Grid for page, Flexbox for components
/* Grid: page structure */
.page {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* Flexbox: header navigation */
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  height: 64px;
}

/* Grid: main content area */
.main {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 24px;
  padding: 24px;
}

/* Flexbox: individual card */
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.card-footer {
  margin-top: auto; /* pushes footer to bottom of card */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Flexbox: footer */
.footer {
  display: flex;
  justify-content: center;
  gap: 24px;
  padding: 24px;
}

In this layout:

There is no conflict between them. A grid item is a flex container. A flex item can contain a grid. They nest cleanly.

Responsive Patterns Without Media Queries

Both Flexbox and Grid can create responsive layouts that adapt to container width without a single @media rule.

Grid: auto-fill vs auto-fit

css — auto-fill vs auto-fit
/* auto-fill: creates empty columns if space allows */
.grid-fill {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
/* On a 900px container with 200px min: 4 columns (1 might be empty) */

/* auto-fit: collapses empty columns, items stretch */
.grid-fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* On a 900px container with 2 items: items stretch to fill */

Use auto-fill when you want consistent column widths regardless of item count. Use auto-fit when you want items to stretch and fill the available space.

Flexbox: Wrapping with Minimum Widths

css — Responsive Flexbox without media queries
.flex-responsive {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.flex-responsive > * {
  flex: 1 1 300px; /* grow, shrink, minimum 300px */
  min-width: 0;    /* allow shrinking below content size */
}

/* Items are at least 300px wide. On narrow screens they stack.
   On wide screens they sit side by side and grow equally. */

Container Queries (Modern Approach)

css — Container queries
.card-container {
  container-type: inline-size;
}

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

/* When the container (not the viewport) is wide enough */
@container (min-width: 500px) {
  .card {
    flex-direction: row;
    align-items: center;
    gap: 24px;
  }
}

Container queries respond to the element's container size rather than the viewport. This makes components truly reusable regardless of where they appear on the page. Combined with auto-fill grids, you can build entire responsive pages with zero viewport media queries.

To verify how your layouts render at different screen sizes, the Responsive Tester previews any URL at common device widths simultaneously.

Common Layout Recipes

Sticky Footer

css — Footer stays at the bottom
/* Grid approach */
body {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

/* Flexbox approach */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1; /* main content takes all available space */
}

Sidebar Layout

css — Fixed sidebar + scrollable content
.layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  height: 100vh;
}

.sidebar {
  overflow-y: auto;
  border-right: 1px solid var(--border);
  padding: 24px;
}

.main-content {
  overflow-y: auto;
  padding: 24px;
}

@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
  }
  .sidebar {
    display: none; /* or toggle with JS */
  }
}

Masonry-Style (CSS Grid)

css — Approximate masonry with grid
.masonry {
  columns: 3;
  column-gap: 16px;
}

.masonry-item {
  break-inside: avoid;
  margin-bottom: 16px;
}

/* True CSS masonry (Chrome 128+, Firefox behind flag) */
.masonry-native {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-template-rows: masonry;
  gap: 16px;
}
CSS Masonry in 2026

Native CSS masonry via grid-template-rows: masonry is shipping in major browsers throughout 2026. Until full support lands, the CSS columns property or a JavaScript library like Masonry.js are the reliable fallbacks. Check Can I Use for current support.

Performance Considerations

For the vast majority of web pages, Flexbox and Grid performance is identical and not a bottleneck. Layout calculations happen in microseconds. But if you are building applications with thousands of DOM elements (data tables, virtual lists, complex dashboards), a few things matter:

When converting your CSS to frameworks like Tailwind, the CSS Unit Converter helps translate between px, rem, em, and viewport units to maintain consistent sizing.

CSS Layout Tools


Frequently Asked Questions

Use Flexbox when your layout flows in one direction (a row of navigation links, a column of form fields, or a toolbar with items that need flexible spacing). Use Grid when you need to control placement in both rows and columns simultaneously (page layouts, card grids with consistent sizing, dashboards, or any layout where items need to align to a two-dimensional grid). In practice, most pages use both: Grid for the overall page structure and Flexbox for the components inside each grid area. They are complementary tools, not competitors.

For most real-world layouts, the performance difference between Grid and Flexbox is negligible. Both are highly optimized in modern browsers. Grid can be slightly faster for complex two-dimensional layouts because it calculates row and column sizes in a single pass, while achieving the same layout with nested Flexbox containers requires multiple layout passes. Flexbox can be marginally faster for simple one-dimensional layouts because it has fewer constraints to resolve. The performance difference only becomes measurable with thousands of elements on screen simultaneously. Choose based on which model fits your layout, not on micro-benchmarks.

Yes, and this is the recommended approach. Grid and Flexbox solve different problems and work well together. A common pattern is using Grid for the overall page layout (header, sidebar, main content, footer) and Flexbox for arranging items within each section (navigation links in the header, cards within the main content area, icon groups in the footer). A grid item can itself be a flex container, and a flex item can be a grid container. There is no conflict between them. Use each where it is the natural fit.

Both Flexbox and Grid use the same alignment properties (justify-content, align-items, align-self, gap), but they apply them differently. In Flexbox, justify-content distributes space along the main axis (the direction items flow) and align-items aligns items along the cross axis. In Grid, justify-content and align-content distribute space for the entire grid within its container, while justify-items and align-items control how items sit within their grid cells. Grid also has place-items and place-content shorthands that set both axes at once. The key difference is that Flexbox alignment is relative to the flex direction (which can change), while Grid alignment is always relative to the row and column axes.

Yes. As of 2026, CSS Grid has full support in every modern browser including Chrome, Firefox, Safari, Edge, and all Chromium-based browsers. Global browser support exceeds 97% according to Can I Use data. The original Grid specification has been supported since 2017. Newer features like subgrid are supported in Firefox (since 2019), Chrome and Edge (since 2023), and Safari (since 2022). The only browsers without Grid support are Internet Explorer 11 and older, which are no longer maintained. You can use CSS Grid in production without any polyfills or fallbacks for modern browser targets.

Use grid-template-columns with auto-fill or auto-fit and the minmax() function. The pattern grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)) creates a grid that automatically adjusts the number of columns based on the container width. Each column is at least 250px wide and grows equally to fill available space. auto-fill creates empty columns if there is extra space, while auto-fit collapses empty columns so existing items stretch to fill the row. This single line of CSS replaces multiple media queries and works for card grids, image galleries, product listings, and any layout where items should wrap responsively. For finer control, combine minmax with clamp() or container queries.

NT

Christian Bucher

We build free developer tools for CSS, layout, design, and more. 269 tool pages, all browser-based, no signup required.

269 Developer Tools, One Place

Browse 269 indexed tool pages with no QTool account required, and inspect the source on GitHub.

Open Source — Free Forever Try Free Tools

Related Tools

CSS Box Shadow Generator · Emoji Picker & Search · Free JSON to YAML Converter

Related Tools

Free JSON to YAML Converter · CSS to Tailwind Converter - Free Tool · Universal Unit Converter

Related Articles

Built by Miguel

Need a custom tool or website?

From . Delivered in 24-48h. You own the code.

View Services →