Tags: web-dev concept

Flexbox

Date: 2026-09-27


Flexbox lays items out along one axis. It starts each item at its flex-basis, then shares out the leftover space by flex-grow, or the overflow by flex-shrink. Nearly every confusing flex result is that arithmetic, plus the hidden min-width: auto that stops items shrinking below their content.


Flexbox is a one-dimensional layout mode: a flex container places its children in a row or column, and distributes space between them according to each item’s flex values. One-dimensional means it reasons about one line at a time — even when items wrap, each line is sized independently of the others, which is the real difference from Grid.

The two axes

flex-direction: row

 main axis ─────────────────────────────────────▶   justify-content
 ┌──────┐ ┌────────────┐ ┌────┐                     (distributes along)
 │  A   │ │     B      │ │ C  │   ▲
 └──────┘ └────────────┘ └────┘   │ cross axis      align-items
                                  ▼                 (aligns across)

justify-* is the main axis, align-* is the cross axis. Change flex-direction to column and they swap physical directions — which is why “justify-content: center doesn’t centre vertically” in a row container.

The algorithm

flex is shorthand for three values: grow shrink basis.

container 600px, three items, no gap

                basis   grow  shrink
A  flex: 0 1 auto  100     0     1      ← content width 100
B  flex: 1 1 0     0       1     1
C  flex: 2 1 0     0       2     1

step 1  sum of bases          100 + 0 + 0 = 100
step 2  free space            600 − 100   = 500
step 3  share by grow         B gets 1/3 × 500 = 167
                              C gets 2/3 × 500 = 333
result  A 100 · B 167 · C 333

flex-grow shares out free space, not total width. flex: 1 and flex: 2 only give a 1:2 ratio of total width when both bases are zero — which is exactly what the shorthand does:

flex: 1      →  1 1 0%      basis 0: widths split purely by ratio
flex: auto   →  1 1 auto    basis = content: bigger content, bigger item
flex: none   →  0 0 auto    rigid: content size, never grows or shrinks
(default)    →  0 1 auto    content size, can shrink, won't grow

Shrinking works the same way in reverse, except overflow is shared out weighted by basis × shrink, so larger items give up more.

The minimum-size trap

A flex item’s min-width defaults to auto, which means it won’t shrink below its content’s minimum width — the longest word, a wide image, a pre block, or a child with white-space: nowrap.

/* a sidebar + main layout where main contains a long URL or a code block */
.layout  { display: flex; }
.sidebar { flex: 0 0 240px; }
.main    { flex: 1; min-width: 0; }   /* ← without this, main refuses to shrink
                                          and the page scrolls sideways */

min-width: 0 (or overflow: hidden) on the flexible item is the fix for most “flex item is overflowing its container” bugs. The column equivalent is min-height: 0, and it’s why nested scrolling panels don’t scroll.

Flex or grid

Use flexbox whenUse grid when
The content decides the size — nav items, tags, a button with an iconThe layout decides the size — columns that line up
One row or column, or wrapped rows that don’t need to alignItems in different rows must align with each other
Pushing one item away: margin-left: autoPlacing items into named regions

Wrapped flex rows are the tell: if you’re setting width: 33.33% on items to make wrapped rows line up, you wanted grid.

Failure modes

  • Overflow from min-width: auto, above. The most common flex bug by a distance
  • width on a flex item is only a suggestion. It feeds flex-basis: auto but shrinking still applies; use flex-basis or flex: 0 0 X if it must be fixed
  • Visual order ≠ DOM order. order and flex-direction: row-reverse move things visually, but keyboard focus and screen readers follow the source — Keyboard Navigation
  • Percentage heights inside flex columns that resolve to nothing because the container has no definite height

Where it connects

  • The Box Model — margins don’t collapse inside a flex container
  • Grid — the two-dimensional counterpart
  • Logical Properties — row already follows writing direction; flex was logical before the logical properties existed