Flexbox
IntermediateOne-dimensional layout: a row or a column, with control over how the free space is distributed. It is the right tool for components, toolbars and anything that must adapt to its content.
Overview
Flexbox lays out children along a single axis and gives you precise control over what happens to the leftover space — or the shortfall. That makes it the natural fit for the small-scale problems that fill an interface: a header with a logo on one side and navigation on the other, a card whose button sticks to the bottom, a row of tags that wraps. The single idea to internalise is the main axis and the cross axis, because every property is defined relative to them and flex-direction swaps which is which.
The Axes
justify-content follows the main axis, align-items the cross axis — and direction swaps them.
.row {
display: flex;
flex-direction: row; /* main = horizontal, cross = vertical */
justify-content: space-between; /* along the MAIN axis */
align-items: center; /* along the CROSS axis */
gap: 1rem; /* never margins between items */
}
/* Change the direction and both meanings swap: */
.col { flex-direction: column } /* main = vertical, cross = horizontal */
/* now justify-content moves items UP and DOWN */
/* justify-content: flex-start | center | flex-end
space-between | space-around | space-evenly
align-items: stretch (default) | flex-start | center | flex-end
baseline */
/* align-items: stretch is the default, which is why two cards in a
row are automatically equal height — a genuinely useful default. */
/* Per-item override */
.logo { align-self: flex-start }
/* The classic header, in three lines */
header { display: flex; justify-content: space-between; align-items: center }flex-grow, shrink and basis
How space is distributed. The shorthand values you will actually type.
/* flex: <grow> <shrink> <basis> */
.item { flex: 0 1 auto } /* the DEFAULT: do not grow, may shrink */
.item { flex: 1 } /* = 1 1 0 — grow to fill, ignore content
width, so equal siblings end up equal */
.item { flex: auto } /* = 1 1 auto — grow, but from the
content's natural width */
.item { flex: none } /* = 0 0 auto — never grow, never shrink */
/* The most common pattern: a fixed sidebar and a filling main */
.sidebar { flex: 0 0 250px }
.main { flex: 1; min-width: 0 }
/* min-width: 0 is the fix for the single most common flex bug:
a flex item will not shrink below its content's minimum size, so
a long unbreakable string or a nested overflow container makes
the whole row overflow instead of scrolling. */
.main { min-width: 0 } /* on rows */
.col { min-height: 0 } /* on columns */
/* Wrapping */
.tags { display: flex; flex-wrap: wrap; gap: .5rem }
.tags > * { flex: 1 1 12rem } /* wraps at 12rem — responsive
with no media query at all */Patterns
The layouts flexbox is genuinely best at.
/* Push the last item away — no floats, no absolute positioning */
.toolbar { display: flex; gap: 1rem }
.toolbar .spacer { margin-inline-start: auto }
/* auto margins absorb all the free space on that side. */
/* Card with a footer pinned to the bottom, whatever the body height */
.card { display: flex; flex-direction: column; height: 100% }
.card__body { flex: 1 } /* takes all the slack */
.card__footer { margin-block-start: auto } /* equivalent */
/* Sticky page footer */
body { min-height: 100dvh; display: flex; flex-direction: column }
main { flex: 1 }
/* Media object: fixed image, flexible text */
.media { display: flex; gap: 1rem; align-items: flex-start }
.media img { flex: none; width: 4rem }
.media__body { flex: 1; min-width: 0 }
/* Centring, both axes */
.center { display: flex; align-items: center; justify-content: center }
/* Choosing: flexbox when the CONTENT decides the sizes and you care
about one axis. Grid when YOU decide the structure in two axes. */Key Points to Remember
- 1justify-content works along the main axis and align-items along the cross axis — flex-direction swaps which is which
- 2align-items: stretch is the default, which is why flex siblings become equal height for free
- 3flex: 1 means grow from a zero basis, giving equal widths; flex: auto grows from the content width
- 4min-width: 0 on a flex item is the fix for content that refuses to shrink and overflows the row
- 5An auto margin absorbs all free space on that side, which pushes an item to the end without floats
Interview Questions
Sign in to ask AriaWhat is the difference between justify-content and align-items?
What does flex: 1 expand to, and how does it differ from flex: auto?
Why does a long string inside a flex item overflow the container, and what fixes it?
Ask Aria about Flexbox
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.