Kuan Kuan - 2 months ago 7
CSS Question

Why do flex items wrap instead of shrink?

I wonder if anyone could give me a simple intro about how flexbox layout gets calculated, especially in which priority order, for example:



<div id="container" style="display: flex; flex-direction: row; flex-wrap:wrap;">
<div style="flex: 1 0 200px; height:200px; background-color: lightgreen;"></div>
<div style="flex: 1 1 400px; height:200px; background-color: lightyellow;"></div>
<div style="flex: 1 0 200px; height:200px; background-color: lightblue;"></div>
</div>





I find it interesting that if I make the container width smaller than 600px; the wrap will take effect first before the shrinking (I set the second yellow block to
flex: 1 1 400px;
) which turn into 3 rows, then the shrinking take effect until container reach 200px;

I wonder what is the order/rule the flexbox layout get decided? Why it does not just shrink from 400 block?

And even I also set all three blocks to
flex: 1 1 their basis size;
the wrap still happens first.

Thanks

Answer

The flex-shrink property comes in handy in a single-line flex container (flex-wrap: nowrap).

In other words, when the flex items cannot wrap, flex-shrink will enable them to shrink when the container is too small (the spec calls this negative free space). This has the effect of preventing flex items from overflowing the container.

However, in a multi-line flex container (flex-wrap: wrap) no negative free space is created because flex items can create additional lines.

You have a row-direction, wrap-enabled flex container with three flex items.

  • div #1 ~ flex: 1 0 200px
  • div #2 ~ flex: 1 1 400px
  • div #3 ~ flex: 1 0 200px

When the container is greater than 800px, all items stay on the line.

When the container breaks below 800px, div #3 will wrap (there is no need to shrink, even if it could).

At the 600px mark (the combined width of divs #1 & #2), div #2 wraps. Again, no need to shrink.

#container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
div:nth-child(1) {
  flex: 1 0 200px;
  height: 200px;
  background-color: lightgreen;
}
div:nth-child(2) {
  flex: 1 1 400px;
  height: 200px;
  background-color: lightyellow;
}
div:nth-child(3) {
  flex: 1 0 200px;
  height: 200px;
  background-color: lightblue;
}
<div id="container">
  <div></div>
  <div></div>
  <div></div>
</div>

From the spec:

flex-shrink

[This property] specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.