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>