Flexbox Alignment Deep Dive
justify-content, align-items, align-self, align-content — main vs cross axis, wrapping lines, and absolute positioning inside flex.
- css
- flexbox
- alignment
Flex alignment is easy until wrapping, auto margins, and axis flipping collide. Everything hinges on main axis vs cross axis, which depend on flex-direction — not on “horizontal vs vertical” forever.
Docs: MDN aligning items, Box alignment.
Axis map
flex-direction |
Main axis | Cross axis |
|---|---|---|
row |
horizontal | vertical |
row-reverse |
horizontal (reversed) | vertical |
column |
vertical | horizontal |
column-reverse |
vertical (reversed) | horizontal |
.row {
display: flex;
flex-direction: row;
justify-content: space-between; /* main */
align-items: center; /* cross */
}
justify-content (main axis)
Pack flex lines’ items along the main axis when free space exists:
flex-start/start/left(with caveats)flex-end/endcenterspace-between/space-around/space-evenly
.nav {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem; /* gap often replaces space-* hacks */
}
With gap, prefer flex-start + margin-inline-start: auto on a group for “push the rest endward”:
.nav__actions {
margin-inline-start: auto;
display: flex;
gap: 0.5rem;
}
align-items & align-self (cross axis)
align-items sets the default cross-axis alignment for all items on a line.
stretch(default) — fill cross size if height/width autoflex-start/center/flex-end/baseline
.form-row {
display: flex;
align-items: flex-end; /* bottom-align labels + controls */
gap: 0.75rem;
}
.form-row .hint {
align-self: center; /* override one item */
}
baseline alignment is gold for mixed text sizes in a toolbar.
align-content (multi-line only)
When flex-wrap: wrap creates multiple lines, align-content distributes those lines on the cross axis. It does nothing useful with a single line (people confuse it with align-items).
.chips {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
gap: 0.5rem;
min-height: 6rem;
}
Values mirror justify-content-style packing: stretch, space-between, center, etc.
Absolute positioning inside flex
.card {
display: flex;
position: relative;
}
.card__badge {
position: absolute;
inset-block-start: 0.5rem;
inset-inline-end: 0.5rem;
}
Absolutely positioned children are not flex items; they don’t participate in flex packing. The flex container is their containing block if it has position not static (or another CB rules apply).
stretch interactions
.equal-cards {
display: flex;
align-items: stretch; /* default */
}
.equal-cards .card {
/* height auto → stretch to tallest item’s line */
display: flex;
flex-direction: column;
}
.equal-cards .card button {
margin-block-start: auto; /* pin footer actions */
}
Interview out-loud
“justify-content aligns on the main axis; align-items on the cross axis; align-self overrides one item; align-content packs wrapped lines. Axes follow flex-direction. I use gap and auto margins for practical toolbars, and I don’t expect align-content to work on a single line.”
Footguns
- Swapping justify/align after changing to
flex-direction: column. align-contentvsalign-itemsconfusion.stretchignored when items have fixed cross-size.space-betweenwith one item — looks like start.- Centering text with
align-itemsinstead oftext-alignwhen the item is full width.
Safe alignment defaults for toolbars
.toolbar {
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
}
.toolbar > .spacer {
flex: 1 1 auto;
min-width: 0.5rem;
}
A flex spacer item (or margin-inline-start: auto on the next group) is clearer than justify-content: space-between when the toolbar wraps — wrapped rows with space-between often look uneven.
Related
Further reading
Related guides
- Centering Everything in CSSCenter with flex, grid, margin auto, and inset — horizontal, vertical, and both — plus the absolute-position and text-align traps.
- CSS Grid vs Flexbox When to UseOne-dimensional flex vs two-dimensional grid — decision rules for navs, card grids, page shells, and nested layouts.
- Flex Grow Shrink BasisHow flex items resolve size — flex-basis first, then grow into free space and shrink on deficit, plus min-width:auto overflow fixes.
- Flexbox FundamentalsFlex container vs items, main vs cross axis, grow/shrink/basis, alignment, wrapping, and the bugs that show up in real layouts.
- Accent Color and Form ControlsUse accent-color to theme native checkboxes, radios, ranges, and progress — what it paints, what it skips, and when to custom-style instead.