He obtained the same by an innocent coincidence, that is, in this particular situation resulted in the same thing, being two child elements and using 50%. Not always - in fact almost never - will have that sort in development.
width
sets the width of the widget, no matter the rest;
flex-basis
defines the initial element reference before to distribute space;
flex-grow
defines how the parent element space will be distributed among the children;
We must remember that by default, flex
will have the value 0 1 auto
, what configures flex-grow
like 0, flex-shrink
as 1 and flex-basis
as auto
.
Width
Thus, using width
in the child elements with the father flex
will have a peculiar behavior due to the fact that being flex
the space will be distributed among the children enlarging them according to their rules or shortening them if it occurs overflow in the parent element. It turns out to put width: 50%
in two elements children you mask the behavior of flex
, because naturally it will occupy the entire width of the parent element without overflow. However, try to put more child elements or a width greater than 50%:
Flex parent element with children over 50%
.pai {
display: flex;
background: lightgray;
}
.filhos {
width: 80%;
border: 1px solid black;
}
<div class="pai">
<div class="filhos">short</div>
<div class="filhos">looooooooooooooong</div>
</div>
What happens is that the property width: 80%
will be ignored due to overflow occurring in the parent element and therefore the 80% will no longer be followed, keeping the basic rule defined by flex
.
Flex parent element with more than two children
.pai {
display: flex;
background: lightgray;
}
.filhos {
width: 50%;
border: 1px solid black;
}
<div class="pai">
<div class="filhos">short</div>
<div class="filhos">looooooooooooooong</div>
<div class="filhos">short</div>
</div>
Similarly, when there are more than two elements with 50% width again the overflow in the parent element would occur, causing the elements to reduce to approximately 33% of the total width (to 3 children).
That is, the width
does not do what it seems to do, only produced the result expected by coincidence of having used the correct values.
Flex-Grow
To property flex-grow
determines how the free space available in the parent element will be distributed to the child elements. You used flex-grow: 1
, which determines that all child elements will grow equally. The coincidence that occurred in this case was that both elements have exactly the same content: none. Possessing the same content the elements will grow identically, but if one element has a different content width than the other, this does not occur. Let’s take an example:
Child elements with flex-Grow:1 and distinct content
.pai {
display: flex;
background: lightgray;
}
.filhos {
flex-grow: 1;
border: 1px solid black;
}
<div class="pai">
<div class="filhos">short</div>
<div class="filhos">looooooooooooooong</div>
<div class="filhos">short</div>
</div>
The second child has a different content than the other two. Not only different but bigger. We further determine that the free space of the parent element should be divided equally for the child elements - and this does not mean that the children will have the same width at the end. If I want to divide R $ 30,00 equally between 3 people, I will give R $ 10,00 each. If one of the three people already initially has more money than the others, she will naturally have more money after I give the R $ 10,00. The same goes for the child elements. Inspect the result of the above example and you will see that the second element will be larger than the other two.
What defines the reference width is precisely flex-basis
. As we commented initially, by default flex-basis
will have the value auto
, which shall take into account the value of width
, which by default will also have the value auto
. Thus, the elements grow considering the initial width.
Flex-Basis
To property flex-basis
will determine what the reference will be for an element to grow within an element flex
. By default the value will be auto
, which, depending on the element, will consider the minimum width of the element according to its content, however you can determine a specific width as reference and all elements will be resized from it.
Child elements with flex-Basis: 50%
.pai {
display: flex;
background: lightgray;
}
.filhos {
flex-basis: 50%;
border: 1px solid black;
}
<div class="pai">
<div class="filhos">short</div>
<div class="filhos">looooooooooooooong</div>
<div class="filhos">short</div>
</div>
What will happen in this example is that, other than just using the flex-grow
, the reference width shall be 50% of the parent element. In this way, the three child elements will start from the same reference width and when resized by the flex will have the same final width. When inspecting the result you will see that the three elements have the same width. The coincidence was to have only two child elements, starting from the same reference width, being resized to the same final value.
In conclusion, the three properties do not do the same thing. A width
determines the width of the element, regardless of how it will resize; and flex-grow
determines how the element will be resized considering the empty space in the parent element and flex-basis
determines which reference width before resizing the element with flex-grow
.
What I must consider to choose between one and the other?
You do not consider between one or the other, they are complementary to each other and use the ones you need to get the desired result.
- I need elements that occupy half the parent element:
width: 50%
, without flex
;
- I need elements that occupy the entire width of the parent element growing equally:
flex-grow: 1
;
- I need elements that grow from the same value:
flex-basis: 1
;
For your example, if you need the elements to have at all times 50% of the width of the parent element, use the width: 50%
and forget the flex
. If you want them grow until they occupy the entire parent element, use flex-grow: 1
. If you need them to have the same width at the end, use flex-basis
to define the same reference.
An explanation with several examples: https://origamid.com/projetos/flexbox-guia-completo/
– Costamilam
This guide is really good!
– hugocsl