Code of the Day
IntermediateLayout Systems

Flexbox Basics

Flexbox is a one-dimensional layout model — it controls arrangement along a single axis, making row or column layouts simple to build and modify.

Web FoundationsIntermediate8 min read
Recommended first
By the end of this lesson you will be able to:
  • Apply display flex to a container and observe the effect on its children
  • Explain the difference between the main axis and the cross axis
  • Control wrapping behavior with flex-wrap
  • Use flex-grow, flex-shrink, and flex-basis to size flex items
  • Apply gap to space flex items without margin hacks

Flexbox solves a specific problem: arranging items along one direction — horizontally or vertically — and distributing the available space among them. Before Flexbox, developers faked this with floats, inline-block, and tables. Those hacks are gone. One line of CSS replaces them.

Turning a container into a flex container

Add display: flex to any element and its direct children immediately become . The element itself becomes a .

.nav {
  display: flex;
}
<nav class="nav">
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="/contact">Contact</a>
</nav>

Before: three <a> elements stacking vertically (they are inline, but the block context of the parent groups them line by line). After display: flex: they line up horizontally in a row, all on the same baseline. No floats, no inline-block, no clearing.

Main axis and cross axis

Every flex container has two axes. The is the direction items are laid out along; the is perpendicular to it.

flex-direction sets the main axis:

.row    { display: flex; flex-direction: row; }    /* default: left → right */
.column { display: flex; flex-direction: column; } /* top → bottom */

Keeping track of which axis is "main" is not optional — every alignment property in Flexbox refers to one of the two axes. Getting them confused is the most common source of Flexbox frustration. The next lesson is entirely about alignment; the axis model is the prerequisite.

Wrapping

By default, flex items squeeze onto a single line even if they overflow their container (flex-wrap: nowrap). Setting flex-wrap: wrap lets items spill onto additional lines when they run out of room:

.card-row {
  display: flex;
  flex-wrap: wrap;
}

With wrapping, each new line starts a fresh mini-flex-container along the main axis. That has alignment implications you will see in the next lesson when you encounter align-content.

gap

The gap property adds space between flex items without touching their outer margins — a clean replacement for the old margin-right: 12px on every item except the last:

.nav {
  display: flex;
  gap: 16px;
}

gap also accepts two values: gap: row-gap column-gap. Since Flexbox is one-dimensional, the relevant one depends on the main axis direction. Both values work; the browser applies whichever is between items.

gap in Flexbox is the same property used in Grid. Learning it once applies to both layout systems.

Sizing flex items: grow, shrink, and basis

Three properties control how each flex item sizes itself within the available space:

  • flex-basis — the item's starting size before free space is distributed. Think of it as the item's "ideal" width (or height, on a column axis). Defaults to auto, which uses the item's content size.
  • flex-grow — a unitless number. If there is leftover space in the container, it is divided among items proportional to their flex-grow values. 0 means "do not grow"; 1 means "take a share."
  • flex-shrink — the reverse: how much an item shrinks if items collectively overflow. 1 (the default) means all items shrink equally; 0 means "never shrink this item."

The flex shorthand composes all three in order: flex: grow shrink basis.

/* All items grow and shrink equally, starting at zero width */
.item { flex: 1 1 0; }

/* Shorthand: flex: 1 expands to flex: 1 1 0 */
.item { flex: 1; }

flex: 1 is the most common value you will write. It tells every item: take an equal share of the available space, grow if there is more, shrink if there is less.

.sidebar { flex: 0 0 240px; }  /* fixed-width, never grows or shrinks */
.main    { flex: 1; }           /* takes all remaining space */

Avoid setting width on flex items when you mean flex-basis. The flex-basis property cooperates with the flex algorithm; a hard width can override the algorithm and produce surprising results — especially when combined with flex-shrink.

A complete minimal example

.toolbar {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 8px;
}

.toolbar .spacer { flex: 1; }   /* pushes whatever follows to the right */
<div class="toolbar">
  <button>Save</button>
  <button>Export</button>
  <div class="spacer"></div>
  <button>Settings</button>
</div>

Save and Export sit on the left; Settings is pushed to the right by the invisible spacer that consumes all the remaining space. This pattern — a zero-content element with flex: 1 acting as a spring — appears constantly in real interfaces.

Where to go next

You can place items on an axis and size them. Next: Flexbox Alignment — how to position items along and across each axis using justify-content, align-items, and the rest of the alignment family.

Finished reading? Mark it complete to track your progress.

On this page