Flexbox is the CSS layout module built for arranging items along a single row or column, and it's still the tool reached for most often when aligning a navbar, spacing out a button group, or building a card row. This guide covers every container and item property, the parts people get stuck on most (flex-direction, wrapping, and spacing), real layout recipes, a flexbox vs. grid comparison, and a compact cheat sheet at the end.

Flex Containers and Flex Items

Flexbox works in a parent/child relationship. Turn any element into a flex container with display: flex (or inline-flex to keep the container itself inline). Every direct child automatically becomes a flex item and follows flexbox's alignment rules, no extra markup required.

.container {
  display: flex;
}

Two axes matter here: the main axis runs in the direction set by flex-direction, and the cross axis runs perpendicular to it. Properties starting with justify- work along the main axis; properties starting with align- work along the cross axis. That single rule of thumb resolves most flexbox confusion.

flex-direction: Row vs. Column

flex-direction sets the main axis and, by extension, decides whether your layout reads as a row or a column.

What is the default value of flex-direction? It's row. If you don't set flex-direction at all, items lay out left-to-right on a single horizontal line.

1
2
3
/* default: row */
.container {
  display: flex;
  flex-direction: row; /* optional, this is the default */
}
1
2
3
.container {
  display: flex;
  flex-direction: column;
}

All four values:

ValueEffect
rowDefault. Items placed left-to-right in a horizontal line.
row-reverseSame axis, items placed right-to-left.
columnItems placed top-to-bottom in a vertical line.
column-reverseSame axis, items placed bottom-to-top.

Reversing order? row-reverse and column-reverse only change the visual order. The underlying DOM order, keyboard tab order, and screen reader reading order stay exactly as written in your HTML. For layouts where reading order matters, reorder the markup itself instead of relying on a reverse value alone.

Controlling How Many Items Fit Per Row

This is one of the most common flexbox questions, and it trips people up because flexbox has no direct "items per row" or "column count" setting the way CSS Grid does. Two properties get you there instead.

flex-wrap decides whether items are forced onto one line or allowed to wrap onto multiple lines once they run out of room:

.container {
  display: flex;
  flex-wrap: wrap; /* default is nowrap */
}

Then give each item a flex-basis (or plain width) that's a fraction of the container. Roughly three items per row, accounting for gap:

.item {
  flex: 1 1 calc(33.333% - 1rem);
}

Want an exact, guaranteed count regardless of content length? That's what CSS Grid's repeat() function is built for: grid-template-columns: repeat(3, 1fr) gives you exactly three columns every time. Our CSS Grid Generator builds that output visually if you'd rather not write it by hand. See the flexbox vs. grid comparison below for when to reach for which.

flex-flow is shorthand for flex-direction and flex-wrap together: flex-flow: row wrap;.

Spacing Between Flex Items

Use gap on the container to add consistent spacing between items without margin hacks:

.container {
  display: flex;
  gap: 1rem; /* space between every item, both axes when wrapped */
}

Split it into row-gap and column-gap if you need different spacing on each axis. gap is well supported across modern browsers and is the current standard, replacing older tricks like negative margins on the container plus matching positive margins on items.

Full Property Reference

Container properties

PropertyValuesDoes
displayflex, inline-flexTurns the element into a flex container.
flex-directionrow (default), row-reverse, column, column-reverseSets the main axis.
flex-wrapnowrap (default), wrap, wrap-reverseAllows items to wrap onto multiple lines.
flex-flow<direction> <wrap>Shorthand for direction + wrap.
justify-contentflex-start (default), flex-end, center, space-between, space-around, space-evenlyAligns items along the main axis.
align-itemsstretch (default), flex-start, flex-end, center, baselineAligns items along the cross axis.
align-contentstretch (default), flex-start, flex-end, center, space-between, space-aroundAligns wrapped lines when there's extra cross-axis space.
gap<length>, default 0Space between items (row-gap / column-gap individually).

Item properties

PropertyValuesDoes
orderinteger, default 0Reorders items visually, lower values first.
flex-grownumber, default 0How much an item grows to fill extra space, relative to siblings.
flex-shrinknumber, default 1How much an item shrinks when space is tight.
flex-basislength or auto, default autoStarting size before growing/shrinking is applied.
flexgrow shrink basisShorthand for the three above, e.g. flex: 1 1 0%.
align-selfauto (default), flex-start, flex-end, center, baseline, stretchOverrides align-items for one item.

Nested Flexbox Patterns

Flex containers nest freely, and this is how most real components are built: a card is a flex column, and its header is a flex row inside that column.

.card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.card-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

The outer card stacks its sections vertically; the inner header keeps its icon and title aligned horizontally, independent of how the outer container is laid out. Each nested flex container has its own independent main and cross axis, nothing about the parent's axis carries down to the child.

Real-World Recipes

Navbar

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}
.navbar nav {
  display: flex;
  gap: 1.5rem;
}

Equal-Height Cards

align-items: stretch is the default, so cards in a flex row are already equal height without extra CSS, as long as you don't override it on the items.

.card-row {
  display: flex;
  gap: 1.5rem; /* align-items: stretch is the default, no extra rule needed */
}
.card {
  flex: 1 1 250px;
}

Centering Anything

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

Sticky Footer

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
main {
  flex: 1; /* grows to push footer down */
}

Skip the syntax, build it visually

Prefer to drag, drop, and see the CSS update live? The Flexbox Generator gives you the same properties from this guide with a real-time preview, plus CSS, Tailwind, and Bootstrap output.

Open the Flexbox Generator →

Using Flexbox with Tailwind CSS

Tailwind maps almost every flexbox property to a utility class directly:

CSSTailwind
display: flexflex
flex-direction: row / columnflex-row / flex-col
flex-wrap: wrapflex-wrap
justify-content: center / space-betweenjustify-center / justify-between
align-items: centeritems-center
align-content: centercontent-center
gap: 1remgap-4
flex-grow: 1grow
flex-shrink: 0shrink-0
flex-basis: 25%basis-1/4
order: 1order-1
align-self: centerself-center

Flexbox vs. CSS Grid

These aren't competing tools, they solve different shaped problems.

FlexboxCSS Grid
DimensionsOne-dimensional (row or column)Two-dimensional (rows and columns at once)
Best forComponent-level alignment: navbars, toolbars, button groups, card rowsPage-level layout: overall page skeleton, dashboards, image galleries
SizingContent-driven; items grow/shrink to fitContainer-driven; explicit tracks defined up front
Exact column countsAchievable but indirect (flex-basis + wrap)Direct (repeat(), grid-template-columns)

In practice, most layouts use both: Grid lays out the page's major regions, and flexbox aligns the content inside each region. If you're building a full 2D layout, try our CSS Grid Generator alongside this guide.

Practice Flexbox Interactively

Flexbox Froggy is a well-known browser game for practicing flexbox properties by moving frogs onto lilypads with CSS. If you'd rather build and export real, usable CSS while you learn instead of solving puzzles, our free CSS Flexbox Generator gives you a live drag-and-drop preview with instant CSS, Tailwind, and Bootstrap output, plus ready-made presets for navbars, sidebars, and holy-grail layouts.

CSS Flexbox Cheat Sheet

A condensed reference for when you already know flexbox and just need the syntax:

Container

display: flex | inline-flex;
flex-direction: row | row-reverse | column | column-reverse;
flex-wrap: nowrap | wrap | wrap-reverse;
justify-content: flex-start | center | space-between | space-around | space-evenly;
align-items: stretch | flex-start | center | baseline;
align-content: stretch | flex-start | center | space-between;
gap: <length>;

Items

order: <integer>; /* default 0 */
flex-grow: <number>; /* default 0 */
flex-shrink: <number>; /* default 1 */
flex-basis: auto | <length>;
flex: <grow> <shrink> <basis>;
align-self: auto | flex-start | center | stretch;

FAQ

Is flexbox still relevant in 2026?

Yes. CSS Grid handles two-dimensional, page-level layout, but flexbox is still the standard for one-dimensional, component-level alignment: navbars, button groups, card rows, form controls. Most real layouts use both together rather than picking one over the other.

What's the difference between "flex" and "flexbox"?

Flexbox (Flexible Box Layout) is the name of the CSS layout module. flex is a shorthand property you set on flex items (flex: 1 1 0%), and display: flex is what turns a container into a flex container. In everyday conversation people use "flex" and "flexbox" interchangeably to mean the whole layout system.

What is the default value of flex-direction?

row. Items lay out left-to-right along a horizontal main axis unless you set flex-direction to column, row-reverse, or column-reverse.

How do I control how many items appear per row in flexbox?

Flexbox has no direct "items per row" setting. Combine flex-wrap: wrap with a flex-basis or width on each item, e.g. flex-basis: 33.33% roughly produces three per row once gap is accounted for. For an exact, guaranteed column count regardless of content, CSS Grid's grid-template-columns: repeat(3, 1fr) is the more direct tool.

How do I add spacing between flex items?

Use the gap property on the flex container (gap: 1rem, or row-gap / column-gap separately). It's supported in every modern browser and avoids the old margin-and-negative-margin workarounds.

Flexbox vs. CSS Grid: which should I use?

Use flexbox for one-dimensional alignment along a single row or column, like a navbar or a toolbar. Use Grid when you're laying out a page or a component in two dimensions at once, with explicit rows and columns. Many layouts nest both: Grid for the overall page skeleton, flexbox for aligning content inside each grid area.

How do I reverse the order of flex items?

Set flex-direction to row-reverse or column-reverse. This only changes the visual order, not the underlying DOM order, so keyboard tab order and screen reader reading order stay the same as the source HTML. For accessibility-sensitive layouts, prefer reordering the HTML itself over relying on visual reversal alone.

Does flexbox work in all modern browsers?

Yes. Flexbox has had full support in Chrome, Firefox, Safari, and Edge for a decade and is considered a CSS baseline feature. Only legacy browsers like IE11 have partial or buggy support, and IE11 usage is now negligible.