Sharing the leftover space
The container sets the general rules —direction and alignment—; the items
decide how the space is shared on the main axis. Picture them as friends
splitting a bill: some pay an equal share, one insists on always chipping in the
same amount. That's governed by three properties that are almost always written
together using the flex shorthand.
flex-basis: the starting size
flex-basis is the item's base size on the main axis before sharing
leftovers or applying shrinks. It's like a width (or height in a column)
that flexbox uses as a starting point:
.item {
flex-basis: 200px; /* starts at 200px; auto uses the content */
}
flex-grow: how to grow if there's spare space
If after placing all the items with their flex-basis there's leftover
space, flex-grow decides who takes it. It's a proportion factor, not a
size:
.side { flex-grow: 0; } /* doesn't grow (default) */
.center { flex-grow: 1; } /* absorbs ALL the leftover space */
If two items have flex-grow: 1 and another has flex-grow: 2, the latter
receives twice the leftovers each of the others gets.
flex-shrink: how to shrink if space is missing
The other way around: if space is missing, flex-shrink decides who gives
in. Its default value is 1 (everyone shrinks). Set it to 0 so an item
never shrinks below its base, useful for logos or icons:
.logo { flex-shrink: 0; } /* keeps its size even when there's no room */
The flex shorthand: grow shrink basis
In practice you almost never write the three separately, but rather the
flex: <grow> <shrink> <basis> shorthand:
.item { flex: 1; } /* = flex: 1 1 0 → share everything equally */
.item { flex: 0 0 200px; } /* fixed size of 200px, neither grows nor shrinks */
.item { flex: 1 1 300px; } /* starts at 300px and shares the rest */
⚠️ CLASSIC TRAP: the flex shorthand confuses people because flex: 1
does not mean "width 1", it means flex: 1 1 0 (grow, shrink and start from
zero). Keep two in mind: flex: 1 ("share the space among yourselves") and
flex: 0 0 auto ("keep your size") and you're set.
flex: 1is the star pattern: a panel that takes up "whatever is left" next to others of fixed size.
align-self: the exception to align-items
align-self lets a single item align differently from the rest on the
cross axis, overriding the container's align-items:
.container { display: flex; align-items: flex-start; }
.featured { align-self: center; } /* only this one is centered */
order: reorder without touching the HTML
order changes the visual order of the items (by default they all equal
0; lower ones come first). Useful for reordering on responsive, although you
have to use it carefully because the HTML stays the same for screen readers:
.visual-first { order: -1; } /* appears before the others */