See what each flexbox property does on real boxes, and copy the container CSS. Change the direction and watch justify-content and align-items swap axes, which is the most common source of flexbox confusion. The menus include the values people rarely try, such as row-reverse, wrap-reverse and space-evenly, so you can see them before you use them.
justify-content works along the main axis and
align-items across it. Which one is horizontal
depends on flex-direction. With
row, justify moves things left and right; switch to
column and it moves them up and down instead.
Check the direction first when something will not center. Most centering problems come from this swap. Change flex-direction in the control above and the hint line tells you which axis justify-content is working on.
It only takes effect when flex-wrap is on and there is more than one line. It distributes the lines, not the items, so on a single line it has nothing to move.
The shorthand also sets flex-basis: 0%, so items share the space equally regardless of content. flex-grow alone keeps the content size as the starting point, so items come out uneven.
Flex items default to min-width: auto, so they will not shrink below their content, and long unbroken text holds them open. Set min-width: 0 on the item to let it shrink.
gap used to be grid-only, so older code often fakes it with margins on the items and a negative margin on the parent. Every major browser has supported gap in flexbox since Safari 14.1 shipped it in 2021.
Flexbox lays items out along one line and lets them wrap. Grid places them in rows and columns that line up with each other. Switch to grid when you need columns to align across rows. Flexbox has no way to line up items on different wrapped lines.
In practice, most layouts use both: grid for the page skeleton, and flexbox inside a card for its header row.
/* Centre anything, both axes */
.centre { display: flex; justify-content: center; align-items: center; }
/* Navbar: logo left, links right */
.nav { display: flex; justify-content: space-between; align-items: center; }
/* Push the last item to the end without space-between */
.toolbar { display: flex; gap: 8px; }
.toolbar .spacer { margin-left: auto; }
/* Sticky footer inside a card of unknown height */
.card { display: flex; flex-direction: column; min-height: 100%; }
.card .body { flex: 1; } /* takes the slack, pushing the footer down */ /* 1. An item refusing to shrink below its content */
.item {
min-width: 0; /* flex items default to min-width: auto */
overflow: hidden; /* and this is usually needed alongside it */
text-overflow: ellipsis;
white-space: nowrap;
}
/* 2. flex: 1 versus flex-grow: 1 */
.equal > * { flex: 1; } /* basis 0: truly equal columns */
.uneven > * { flex-grow: 1; } /* basis auto: content size decides */
/* The shorthand sets grow, shrink and basis at once:
flex: 1 == flex: 1 1 0% */ Remember min-width: 0 above all. Without it, a long URL or an unbroken string in a flex item holds the entire layout open.
.item { order: -1; } /* moves it first visually */
/* order changes paint order only. Tab focus, screen readers and
copy-paste all still follow the DOM. Using it to rearrange
meaningful content makes the page incoherent for anyone
not using a mouse. Reorder the markup instead. */ gap works in flexbox in every major browser since Safari 14.1 added it in 2021. Older code often fakes it with margins on the items plus a negative margin on the container. If you inherit that pattern, replace it with gap, which removes the edge-margin alignment bugs that come with it.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
The main axis, which flex-direction decides. With row, justify-content moves items horizontally and align-items moves them vertically. Switch to column and the two swap. This swap causes most flexbox centering problems.
Put display: flex, justify-content: center and align-items: center on the container. The child is centered on both axes in either direction, whatever the size of either box.
align-items positions items within their line, and align-content distributes the lines themselves. align-content has no effect unless flex-wrap is on and there is more than one line, which is why it so often appears to be ignored.
It is shorthand for flex-grow: 1, flex-shrink: 1, flex-basis: 0%. The zero basis makes items share the space equally regardless of their content. flex-grow: 1 on its own keeps the content size as the starting point, so items end up uneven.
Flex items have min-width: auto by default, so they will not shrink below their content. Long unbroken text or a wide child holds them open. Set min-width: 0 on the item to let it shrink.
Use flexbox for one dimension: a row of buttons, a navbar, a card's internal stack. Use grid for two: a page layout, a gallery, anything where rows and columns both need to line up. Most layouts use both.
space-around gives every item the same space on both of its sides, so the gap between two items is twice the gap at the container edges. space-evenly makes every gap identical, edges included. Pick space-evenly when the uneven edge spacing looks like a bug, which it usually does. Switch between them in the justify-content menu and compare the end gaps in the preview.
Both reverse the visual order of the items and move the start edge to the other end, so flex-start now packs items against the right or the bottom. A chat log that keeps the newest message at the bottom is the classic column-reverse case. The DOM order does not change, so keyboard focus and screen readers still follow the source, which is why it should stay a visual trick.
It wraps exactly like wrap, but new lines stack in the opposite direction on the cross axis. In a row, the second line appears above the first instead of below it. Items within each line keep their normal order. It is rare in practice, but useful when a toolbar should grow upwards from the bottom of a container rather than pushing content down.
For two-dimensional layouts, the CSS grid generator builds the track definitions. Style the boxes with the box shadow and border radius generators.