Skip to content
Free Tool Arena

How-To & Life · Guide · Developer Utilities

How to Use Flexbox

flex-direction, justify-content, align-items, flex-wrap, flex-grow/shrink/basis, common patterns, and when to pick flex vs grid.

Updated April 2026 · 6 min read

Flexbox is the one-dimensional layout tool CSS should have had since day one. It solves the problems that used to require floats, tables, or absolute positioning: centering a thing vertically, distributing space between elements, making a row of cards behave sensibly when the viewport shrinks. Once flex-direction and justify-content click, 80% of everyday layout work becomes a five-line rule. This guide walks through the core properties in the order they actually matter, shows the patterns you’ll reuse daily, and makes the distinction between flexbox and grid clear enough that you stop reaching for the wrong tool.

Advertisement

The mental model

A flex container has a main axis and a cross axis. flex-direction picks which way the main axis runs. Everything else is “align things along main” or “align things along cross.” Get this mental model right and the property names stop feeling arbitrary.

.container {
  display: flex;
  /* default: flex-direction: row; */
}

As soon as an element is display: flex, its direct children become flex items. Grandchildren are unaffected unless you also flex the child.

flex-direction

Four values: row (default, left-to-right), row-reverse, column (top-to-bottom), and column-reverse. Most layouts use row for horizontal alignment and column for stacking items vertically while still getting flex superpowers.

.navbar  { display: flex; flex-direction: row; }
.sidebar { display: flex; flex-direction: column; }

Switching direction flips the main and cross axes. A row’s main axis is horizontal; a column’s main axis is vertical. Keep this in mind when reaching for justify-content vs align-items.

justify-content: along the main axis

Controls how items spread along the main axis. The values you’ll actually use:

flex-start     pack at the start (default)
flex-end       pack at the end
center         pack in the middle
space-between  first and last pinned, gaps equal between
space-around   equal gaps, including half-gaps at each edge
space-evenly   equal gaps everywhere, including edges

space-between is the workhorse for nav bars: logo on the left, links on the right, no extra wrappers needed.

align-items: along the cross axis

Controls how items line up on the cross axis. Values:

stretch      fill the cross axis (default)
flex-start   top (in row) / left (in column)
flex-end     bottom / right
center       center
baseline     line up text baselines

Centering a thing both ways is now a two-line job:

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

flex-wrap

By default flex items stay on one line and shrink to fit. Add flex-wrap: wrap to let them flow onto multiple rows. This is what makes responsive card grids work without media queries.

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.card {
  flex: 1 1 240px; /* grow, shrink, 240px basis */
}

Cards now sit three-up on a desktop, two-up on a tablet, one-up on a phone, with no breakpoints. Flex decides.

flex-grow, flex-shrink, flex-basis

These three properties on a flex item control how it competes for space. Shorthand: flex: grow shrink basis.

flex-grow — how much extra space this item should soak up (0 = none, 1 = an equal share, 2 = twice the share).

flex-shrink — how willing this item is to give up space when the container is too small (0 = never shrink, 1 = default).

flex-basis — the item’s preferred size before grow and shrink apply. Can be a length (240px) or auto.

.sidebar { flex: 0 0 240px; }  /* rigid 240px column */
.main    { flex: 1 1 auto; }   /* soaks up remaining space */

The gap property

gap sets spacing between items without margins. It works in both flex and grid. Always prefer gap over margin-right on children — no trailing-item hacks, no:last-child overrides.

.row {
  display: flex;
  gap: 16px;       /* 16px between items */
  gap: 16px 8px;   /* 16px row, 8px column when wrapped */
}

Pattern: navigation bar

<nav class="nav">
  <div class="logo">Brand</div>
  <ul class="links">
    <li><a href="/a">One</a></li>
    <li><a href="/b">Two</a></li>
  </ul>
</nav>

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 24px;
}
.links { display: flex; gap: 16px; list-style: none; }

Pattern: card row

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.card {
  flex: 1 1 260px;
  display: flex;
  flex-direction: column;
}
.card__body { flex: 1; }  /* push footer to the bottom */

Nested flex is fine and often necessary: the card itself is a column, its body expands, and the footer stays pinned to the bottom of each card in the row.

Flexbox vs Grid

Flexbox is one-dimensional. Use it when you’re laying things out along a single axis: a nav bar, a toolbar, a stack of form rows, a row of cards.

Grid is two-dimensional. Use it when you need explicit control over both rows and columns: a dashboard, a gallery with consistent rows, a page layout with header/sidebar/main/footer.

Many real layouts mix the two — grid for the page shell, flex for the contents of each cell. They cooperate fine.

Debugging flex

Chrome and Firefox both have flex inspectors. Click the tiny flex badge next to display: flex in DevTools and the browser overlays the axes and free space. If an item isn’t shrinking as expected, it’s almost always flex-shrink: 0 or an explicit width somewhere.

Common mistakes

Mixing up justify-content and align-items. Remember:justify follows the main axis, align follows the cross axis. In a column, justify-content is vertical.

Forgetting that flex items shrink by default. A width: 300px inside a flex container can still become 180px if there’s not enough room. Set flex-shrink: 0 or use flex-basis with grow 0 shrink 0.

Using margins instead of gap. Gaps are cleaner, handle wrapping correctly, and don’t need :last-childexceptions.

Reaching for flex when you want grid. If you’re fighting to get rows to align across columns, you want grid, not flex.

Nesting flex containers for no reason. Each extra display: flex adds complexity. Only flex at levels where you actually need flex behavior.

Setting height on the container to center vertically. The container needs a height for align-items: center to have any vertical space to work with. On a full-viewport centerpiece, use min-height: 100vh.

Run the numbers

Preview flex properties live in the flexbox playground. For two-dimensional layouts reach for the grid layout generator, and when you’re rounding off card corners afterwards the border radius generator keeps your values consistent across the whole layout.

Advertisement

Found this useful?Email