Stop flex items stretching to fill the flex container
The Solution at a Glance
- Stop individual flex items from stretching in the cross direction by setting
align-self
. - Stop the stretching of all flex items at once by keeping
align-self: auto
on flex items and settingon the flex container.
- If your flex container allows flex items to wrap into multiple flex lines with
: wrap
, seton the flex container to stop the flex lines from stretching.
Stretching happens in the cross direction
Flex items and flex lines stretch in the cross direction by default. The cross direction is perpendicular to the main direction, which is set by the flex container with .
The main part of Flexbox, the growing and shrinking of flex items, happens in the main direction. The cross direction is the “other direction”, and doesn’t have the growing or shrinking. All you can do is decide if you want to align or stretch the flex items or flex lines.
Flex items and flex lines don’t grow in the main direction by default. But they do stretch in the cross direction by default.
Why flex items stretch by default
Flex items stretch in the cross direction to fill their flex line. Each flex item separately decides about its cross direction alignment with align-self
.
The initial value of align-self
is auto
, which means “I don’t have a strong opinion, I’ll listen to my flex container’s suggestion”.
The flex container sets to make this suggestion to the flex items that will listen. The initial value of
is
normal
. is used in other layout types, and
normal
might mean something different in those other types. But in Flexbox, normal
is the same as stretch
.
So by default, each flex item listens to the alignment suggestion of the flex container. And the flex container suggests that the flex items should stretch in the cross direction.
Flex items stretch in flex lines, not the flex container itself
But by default, there’s only one flex line, and it’s the same size as the flex container. From this perspective, it’s intuitive to think we’re stretching flex items in the flex container.
There’s only one flex line by default because the flex container doesn’t allow the flex items to wrap into a new flex line. Even if the flex item is about to overflow the flex container.
Whether flex items can wrap or not is controlled by setting on the flex container. The initial value of
is
nowrap
, and that’s why the flex items don’t wrap and there’s only a single flex line.
The flex container can allow the flex items to wrap into new flex lines if they’re about to overflow the flex container. This can be done by setting : wrap
on the flex container.
Once wrapping is allowed, the size of flex lines is no longer the same as the size of the flex container. Which makes sense, because now you can have more than one flex line. Instead, the flex lines are sized based on the size of the flex items inside of them.
The flex lines stretch by default, too
Flex lines stretch in the cross direction by default, if the flex container allows flex items to wrap. In that case, stop the flex lines from stretching by setting on the flex container to something else than the initial
normal
or stretch
.
The order of everything
- Get the cross size of each flex item independent of other flex items, without any stretching.
- If the flex container doesn’t allow flex items to wrap, there’s a single flex line and it’s the same size as the flex container.
- If the flex container does allow flex items to wrap, each flex line is sized so that it fits all the flex items inside.
- If the flex container does allow flex items to wrap, it gets to decide if it wants to stretch the flex lines.
- Now, the flex items get to independently decide if they want to stretch inside the flex line.