2

Been playing around with flexbox, and most of the configurations seem to be making sense. One that doesn't to me though is 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, contrary to what I originally would have thought based on the pictures I have seen from the flexbox w3 site.

It instead gives you rows separated by a margin. I am curious why/how these margins are determined, and why the flex-items do not stretch across its flex-container?

Here is a JSBIN replicating the problem: http://jsbin.com/cehogay/edit?html,css,output

.parent {
  display: flex;
  flex-flow: row wrap;
  width: 80%;
  height: 400px;
  border: solid 5px blue;
  align-items: center;
  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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
the12
  • 2,395
  • 5
  • 19
  • 37

1 Answers1

2

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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • If you look at the example, the lines do not stretch to take the available space (when align-items, and align-content is used), as there is empty space between the rows. Is there something about using align-items, or something about the wrapping that is nullifying the expected behavior (which is the lines should stretch, so there is no empty spaces)? – the12 Jan 24 '17 at 20:53
  • The lines *do* stretch to fill the row. You're looking at the borders. The borders don't represent the line. They represent the flex item. – Michael Benjamin Jan 24 '17 at 20:58
  • 1
    Oh ok. So for the above example, when using `align-items`, you're indicating where you want the flex item on the particular row ("line"). In this case, `align-items:center` would go in the middle of the row. Whereas `align-content`, arranges the rows themselves? – the12 Jan 24 '17 at 21:05