Misinterpreting the flex-grow
value is easy to do. Consider this layout with three tiles having flex-grow
values 1, 1, and 3:
The weights sum to 5. That means that the first two tiles each consume 1/5 of the parent and the third consumes 3/5, right? Wrong. Try inspecting the tiles with your browser's developer tools and you will find that the third tile is not three times as wide as the other two.
But watch what happens when you don't set the width of the tiles:
Try using your developer tools to inspect the widths now. You will find that the third tile is indeed three times as wide as its siblings. In this case, the misinterpretation of flex-grow
as a proportion of a child within its parent happens to be right. But the correctness is accidental.
The misinterpretation is made apparent when content is added. Watch what happens when the first tile gets a paragraph of text:
The first child has eaten up all the horizontal space of the parent. The second and third tiles, even though they have flex-grow
values of 1 and 3, don't appear at all. This is because flex-grow
only applies to the parent's leftover space, not its entire space.
In this case, there is no leftover space. The paragraph element is a block element that consumes all the available width, leaving none for the second and third tiles.
This behavior is explained by examining the formulas that the browser uses to calculate a flex child's expanded size. In a horizontal flex parent, a child's claim on the extra space is computed by applying the proportion of growth to the extra space:
The child's overall width is a combination of this extra space and its basis:
A child's basis is the size of an element before it gets any extra space. It is set using the flex-basis
property. By default, flex-basis
is auto
, which means the basis is set by the width (or height, for vertical containers). If you set flex-basis
to 0, then the child starts with no visible area. See what happens when the bases for all tiles are set to 0:
When the bases are 0, the flex-grow
property does size each child as a proportion of the parent. That's because all the space in the parent is leftover space. None of it went toward satisfying a basis.
This technique of setting bases to 0 is useful when you are trying to create user interfaces that behave like the ones you see in desktop applications. However, with a basis of 0, a child may get so small that it can't be interacted with easily. You may want to also specify a child's min-width
to prevent this.
The interplay between flex-grow
, flex-basis
, width
, height
, and min-width
, and min-height
can get a little murky. Be careful!