🌐

CSS Flexbox or Grid? A Simple Way to Decide

HTML/CSS3 min readUpdated October 2026

Stop guessing between Flexbox and CSS Grid. Learn the one question that decides it, with copy-and-run layouts for navbars, card galleries, and page templates.

Flexbox and Grid both lay out things on a page, so it's easy to wonder which one to reach for. The answer is simpler than most articles make it.

Flexbox lays things out in one direction, a row or a column. Grid lays things out in two directions, rows and columns together.

If you're arranging items along a line, use Flexbox. If you're building a layout with rows and columns that need to line up, use Grid. Everything else is detail. All the examples below run in the HTML editor.

Flexbox: items in a line

A navigation bar is the classic case. You want items side by side with some space between them, and everything vertically centered.

<style>
  .nav {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
    background: #14532d;
    color: white;
    font-family: sans-serif;
  }
  .nav .logo { font-weight: bold; margin-right: auto; }
  .nav a { color: white; text-decoration: none; }
</style>

<nav class="nav">
  <span class="logo">MySite</span>
  <a href="#">Home</a>
  <a href="#">Blog</a>
  <a href="#">Contact</a>
</nav>

Three properties do the work. display: flex turns on the layout. align-items: center handles the cross direction. And margin-right: auto on the logo pushes everything after it to the far edge, a neat trick that saves you a wrapper element.

The most useful Flexbox properties:

  • justify-content spreads items along the main direction (space-between, center, flex-end).
  • align-items aligns them across it.
  • gap adds space between items, so you don't need margins.
  • flex-wrap: wrap lets items drop to the next line when they run out of room.
  • flex: 1 makes an item grow to fill leftover space.

Grid: rows and columns together

A gallery of cards is where Grid shines. With Flexbox, the last row's items stretch or misalign. With Grid, every card sits in a real column.

<style>
  .gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 16px;
    font-family: sans-serif;
  }
  .card {
    background: #f0fdf4;
    border: 1px solid #86efac;
    border-radius: 8px;
    padding: 24px;
    text-align: center;
  }
</style>

<div class="gallery">
  <div class="card">One</div>
  <div class="card">Two</div>
  <div class="card">Three</div>
  <div class="card">Four</div>
  <div class="card">Five</div>
</div>

The magic line is repeat(auto-fill, minmax(160px, 1fr)). It says: "Fit as many columns as you can, each at least 160px wide, and share any leftover space equally." Resize the preview and the number of columns changes by itself, with no media queries.

Grid for whole page layouts

Named areas make page structure readable at a glance.

<style>
  body { margin: 0; font-family: sans-serif; }
  .page {
    display: grid;
    grid-template-columns: 200px 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
      "header header"
      "sidebar main"
      "footer footer";
    min-height: 100vh;
  }
  .page > * { padding: 16px; }
  header  { grid-area: header;  background: #14532d; color: white; }
  aside   { grid-area: sidebar; background: #dcfce7; }
  main    { grid-area: main; }
  footer  { grid-area: footer;  background: #f3f4f6; }
</style>

<div class="page">
  <header>Header</header>
  <aside>Sidebar</aside>
  <main>Main content goes here.</main>
  <footer>Footer</footer>
</div>

You can read the layout straight from the grid-template-areas text. To move the sidebar to the right, change the text. No reordering HTML.

The best answer: use both

They aren't rivals. A typical page uses Grid for the overall structure and Flexbox inside the pieces.

<style>
  .grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; font-family: sans-serif; }
  .tile { border: 1px solid #ccc; border-radius: 8px; padding: 12px; }
  .tile-top { display: flex; justify-content: space-between; align-items: center; }
  .price { font-weight: bold; color: #15803d; }
</style>

<div class="grid">
  <div class="tile"><div class="tile-top"><span>Coffee</span><span class="price">$4</span></div></div>
  <div class="tile"><div class="tile-top"><span>Tea</span><span class="price">$3</span></div></div>
</div>

The tiles sit in a grid. Inside each tile, a flex row puts the name on the left and the price on the right.

A quick decision guide

Pick Flexbox when:

  • You're laying out a toolbar, menu, button group, or form row.
  • The content decides the size, and items should flow naturally.
  • You want to center something both ways.

Pick Grid when:

  • You need rows and columns that line up.
  • You're building a page layout or a card gallery.
  • You want to place items in specific cells or let some span multiple columns.

Mistakes that waste time

Using margins instead of gap. Both Flexbox and Grid support gap, and it doesn't leave extra space at the end.

Text or images overflowing a flex item. Flex items have min-width: auto by default, so long content can refuse to shrink. Add min-width: 0 to the item to let it shrink and truncate properly.

Forgetting that align-items and justify-content swap in a column. When you set flex-direction: column, the main axis is vertical, so justify-content now controls vertical spacing.

Fighting the layout with fixed widths. Prefer fr units, minmax(), and flex: 1, so things adapt to the screen.

Key takeaways

  • One direction: Flexbox. Two directions: Grid.
  • Use gap for spacing in both.
  • repeat(auto-fill, minmax(160px, 1fr)) gives you a responsive gallery with no media queries.
  • Combine them. Grid for the page, Flexbox for the pieces.

Try it yourself

Reading helps, but typing the code is what makes it stick. Open the editor, paste any example from this article, and change it until it breaks.

Open the HTML/CSS editor

Related Articles