align-items aligns individual items along a container's cross axis, but what happens once those items spread across several lines thanks to flex-wrap? A new question comes up: how do the lines themselves get positioned inside the container's total height? That is exactly align-content's job, a property often confused with align-items even though it operates at a different level.
It comes up in layouts where the number of lines created by wrapping is never known ahead of time, like a thumbnail grid that reorganizes depending on screen width or the number of items shown.
Definition
align-content is the property that distributes a Flexbox container's lines along its cross axis, once that container holds more than one thanks to flex-wrap: wrap. It only applies to the container, never to individual children.
.container {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}That declaration spreads the lines created by wrapping across the container's full height, pushing the first line to the top and the last one to the bottom.
The key difference with align-items
Mixing up the two properties is common, even though they operate at completely different levels.
| Property | Acts on | Needs several lines? |
|---|---|---|
align-items | Each item, inside its own line | No, works with just one line |
align-content | The lines themselves, relative to each other | Yes, no effect on a single line |
align-items positions an item vertically inside its own line, while align-content positions the lines relative to one another, across the container's total vertical space. Both properties can perfectly coexist on the same container, each acting at its own level.
Without several lines, no effect at all
This is the most important thing to remember: align-content stays without the slightest effect as long as the container only shows a single line of items, whether that is because flex-wrap is set to nowrap, or simply because everything already fits on one line despite flex-wrap: wrap.
.container {
display: flex;
flex-wrap: wrap;
align-content: center;
height: 400px;
}On this container, align-content: center only produces a visible effect if the content actually overflows onto several lines inside those 400 pixels of height; on a single line, all the leftover vertical space simply gets ignored by this property.
A concrete example
A tag grid held to a fixed height, with a variable number of lines depending on how many tags get shown, shows off align-content's use well.
.tag-list {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
height: 200px;
gap: 0.5rem;
}align-content: flex-start groups every line of tags at the top of the container, leaving the remaining vertical space at the bottom, instead of stretching it out between the lines, which would give a simple keyword list a far too airy look.
The diagnosis pitfall
The most common trap is setting align-content on a container, seeing that nothing happens, and wrongly concluding the property is broken.
flex-wrap: wrap or wrap-reverse, and that its content genuinely overflows onto several lines. Without both conditions met at once, align-content simply has nothing to do, no matter which value gets chosen.Frequently asked questions
align-content also work with CSS Grid?Yes, in a grid context, align-content distributes the grid's rows across the container's height if they take up less space than what is available, a principle very close to its use on Flexbox.
align-content accept the same values as justify-content?Yes, most values are shared: flex-start, flex-end, center, space-between, space-around, plus one extra value, stretch, specific to align-content, which stretches the lines themselves to fill all the container's available vertical space.
align-content have no effect on my container with no defined height?Because align-content distributes the leftover vertical space between the lines, and a container whose height exactly matches its content has precisely no leftover space to distribute. A container taller than the sum of the lines it holds is needed to see any visible effect.