nonopolarity
nonopolarity

Reputation: 151146

should a flex item with flex-grow 0.1 be taking all the extra space or just 10%?

The following third flex item has a flex-grow of non-zero value, which is 0.1. It might be reasonable and I also read a suggestion that it should take up 100% of any extra space, because the other flex items are 0, and cannot grow. This one is 0.1 and even 0.1 / 0.1 is 100% (as a ratio). However, in practice on Chrome and Firefox it only took 10% of the extra space. Why and how should it behave?

#container {
  display: flex;
  border: 1px dashed blue
}

#container div {
  border: 1px dashed orange
}

#container div:last-child {
  flex-grow: 0.1;
  background: #ccc
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Upvotes: 3

Views: 1386

Answers (3)

user12643166
user12643166

Reputation:

However, in practice on Chrome and Firefox it only took 10% of the extra space.

This is correct behaviour.

Find the ratio of the item’s flex grow factor to the sum of the flex grow factors of all unfrozen items on the line. Set the item’s target main size to its flex base size plus a fraction of the remaining free space proportional to the ratio. flexbox-ref

From the above, the flex-grow value effectively indicates the percentage of the free space, and flex-grow: 1 represents 100% of the free space. Also, the size after flex-grow is added is derived by such an equation.

flex item's base size + (remaining free space * (flex item's flex factors / unfrozen flex item's flex factors))

If you specify 0.1 for flex-grow in the context of the question, remaining free space will be 0.1 times the initial free space:

If the sum of the unfrozen flex items’ flex factors is less than one, multiply the initial free space by this sum. If the magnitude of this value is less than the magnitude of the remaining free space, use this as the remaining free space. flexbox-ref

So, using the above formula, the size of the third flex item can be derived as follows:

flex item's base size + (initial free space * 0.1 * (0.1 / 0.1))

= flex item's base size + (initial free space * 0.1)

So the result of flex-grow: 0.1 is 10% of the initial remaining free space.

Upvotes: 6

Temani Afif
Temani Afif

Reputation: 273626

From the specification you can read:

Flex values between 0 and 1 have a somewhat special behavior: when the sum of the flex values on the line is less than 1, they will take up less than 100% of the free space.

You can continue to read the detail of this section and you will understand why your 0.1 is actually 10% of the free space.

The important part:

This pattern is required for continuous behavior as flex-grow approaches zero (which means the item wants none of the free space). Without this, a flex-grow: 1 item would take all of the free space; but so would a flex-grow: 0.1 item, and a flex-grow: 0.01 item, etc., until finally the value is small enough to underflow to zero and the item suddenly takes up none of the free space

Upvotes: 3

Dejan.S
Dejan.S

Reputation: 19158

The minimum is 1 as value for flex-grow. If you add 1 it will take upp the remaining of the space there. Default value is 0 for flex-grow, that is why your two first divs only take up the space that their value do. You will notice that it will behave different using flex-grow, if you take your first div and add flex-grow: 1; it will be the size as your last one. If you on the other hand take flex-grow: 2; it will be larger then the other two, but not twice as large as it could be interrupted it to be. In real projects I rarely use anything but flex-grow: 1;, if I want something to be twice as large or anything along those lines I use flex-basis or width. Hope this helps.

Check my snippet. If you want it to take up a scpecific percentage then use flex-basis or width properties.

#container {
  display: flex;
  border: 1px dashed blue
}

#container div {
  border: 1px dashed orange
}

.remaining-space {
  flex-grow: 1;
  background-color: deepskyblue;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div class="remaining-space">3</div>
</div>

Upvotes: 0

Related Questions