Using flexbox, how does align-content:stretch
work when combined with align-items
?
When you are working with a single-line flex container (flex-wrap: nowrap
), align-content
has no effect. You can use align-items
and align-self
to position flex items.
When you are working with a multi-line flex container (flex-wrap: wrap
), align-content
goes into effect and can be used to pack flex lines in the same way justify-content
works on the main axis.
...how if you set align-content
to stretch (default option), and set align-items: center
, flex-end
, or flex-start
, it does not stretch the rows.It instead gives you rows separated by a margin.
These are not margins. This is align-content: stretch
at work. This setting is taking the length of the container's cross-axis (in this case, height), and distributing that space equally among each line.
Here's the spec definition of stretch
for the align-content
property:
stretch
Lines stretch to take up the remaining space. If the leftover free-space is negative, this value is identical to flex-start
. Otherwise, the free-space is split equally between all of the lines, increasing their cross size.
In other words, align-content: stretch
on the cross axis is similar to flex: 1
on the main axis.
If you switch from align-content: stretch
to align-content: flex-start
, those gaps are gone.
.parent {
display: flex;
flex-flow: row wrap;
width: 80%;
height: 400px;
border: solid 5px blue;
align-items: center;
align-content: flex-start;
}
.child {
width: 200px;
font-size: 20px;
border: solid 2px black;
}
<div class="parent">
<div class="child">22</div>
<div class="child">211212</div>
<div class="child">6666666</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
</div>
Why do the flex-items not stretch across its flex-container?
They do. In your demo, you're probably looking at the black borders. These borders don't represent the line. They represent the flex item.
Each line is exactly the same height because align-content: stretch
has distributed the container space equally among each line. (The height of each row is determined by dividing the height of the container by the number of rows.)
When you use align-items: flex-start
or center
or flex-end
, you are not changing the height of the line. You are re-positioning the flex item within that line. But if you switch to align-items: stretch
, you'll close the gaps.
.parent {
display: flex;
flex-flow: row wrap;
width: 80%;
height: 400px;
border: solid 5px blue;
align-items: stretch;
align-content: stretch;
}
.child {
width: 200px;
font-size: 20px;
border: solid 2px black;
}
<div class="parent">
<div class="child">22</div>
<div class="child">211212</div>
<div class="child">6666666</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
<div class="child">211212</div>
</div>