Skip to content
CSS

CSS Flexbox Guide

Alignment, patterns, and common bugs — the flexbox reference you'll actually bookmark.

stellae.design

8 min read

TL;DR

  • Flexbox is a one-dimensional layout system — it works along a single axis (row or column)
  • Master the three core properties: justify-content (main axis), align-items (cross axis), and gap
  • Use flex: 1 to make items grow equally, flex: none to keep items at their intrinsic size
  • Flexbox is ideal for navbars, card rows, form layouts, and centering — use Grid for full page layouts

The Flex Container

Everything starts with display: flex on the parent. This creates a flex container and turns direct children into flex items.

css
.container {
  display: flex;
  flex-direction: row;       /* default — items flow left to right */
  justify-content: flex-start; /* default — pack items to the start */
  align-items: stretch;       /* default — items stretch to fill container height */
  gap: 1rem;                  /* spacing between items */
}

flex-direction

Controls the main axis. row (default) is horizontal, column is vertical. The cross axis is always perpendicular.

css
/* Vertical stack */
.stack {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Reverse order without changing HTML */
.reversed {
  display: flex;
  flex-direction: row-reverse;
}

flex-wrap

By default, flex items try to fit on one line. flex-wrap: wrap lets them flow to the next line:

css
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tag {
  padding: 0.25rem 0.75rem;
  background: hsl(217, 91%, 95%);
  border-radius: 9999px;
}

Alignment Deep Dive

This is where Flexbox shines. The two key axes:

  • Main axis (direction of flex-direction): controlled by justify-content
  • Cross axis (perpendicular): controlled by align-items
css
/* Center everything — the classic */
.center-all {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

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

/* Push last item to the end */
.card-footer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.card-footer .price {
  margin-left: auto;  /* pushes to the right */
}

The flex Shorthand

The flex property on items controls how they grow and shrink. It's shorthand for flex-grow, flex-shrink, and flex-basis.

css
/* Common patterns */
.item { flex: 1; }       /* grow equally, basis 0 — equal width items */
.item { flex: none; }     /* don't grow or shrink — intrinsic size */
.item { flex: 0 1 auto; } /* default — don't grow, can shrink, auto basis */
.item { flex: 1 1 0; }    /* same as flex: 1 — grow and shrink equally */

/* Sidebar + main content */
.sidebar { flex: 0 0 280px; }  /* fixed 280px, won't grow or shrink */
.main    { flex: 1; }          /* takes remaining space */

Common Patterns

html
<nav class="nav">
  <a href="/" class="nav-logo">Logo</a>
  <div class="nav-links">
    <a href="/about">About</a>
    <a href="/work">Work</a>
    <a href="/contact">Contact</a>
  </div>
</nav>
css
.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
}
css
.card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.card-body {
  flex: 1;  /* grows to push footer down */
}

.card-footer {
  margin-top: auto;  /* alternative: pin to bottom */
}

Holy Grail Centering

css
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

That's it. Three lines. This is why Flexbox exists.

Best Practices

  • Do use gap for spacing — it replaced the old margin hack on flex items
  • Do use flex: 1 for equal-width items instead of calculating percentages
  • Do use margin-left: auto (or margin-top: auto in columns) to push items to the end
  • Don't use Flexbox for two-dimensional grid layouts — use CSS Grid
  • Don't set width on flex items when you should use flex-basis
  • Don't forget min-width: 0 on flex items with text — prevents overflow from long strings

Common Mistakes

  • Text overflow — flex items have min-width: auto by default. Long words or URLs won't shrink below their content size. Fix with min-width: 0 and overflow: hidden
  • Centering with margin: auto — this works, but justify-content and align-items are clearer and more maintainable
  • Mixing flex and width — width: 33.33% on a flex item ignores the gap. Use flex: 1 instead
  • Forgetting flex-wrap — items will overflow the container on small screens if you don't wrap

Tools to Explore

  • Flexbox Playground — visually experiment with every flex property
  • Spacing Calculator — generate consistent spacing scales for your flex layouts
CSScss

Was this article helpful?