Greediness of flex elements in CSS
Let's say we now have two flex blocks lined up in a row. These blocks are set to a width of 100px, and their parent is set to 300px:
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
</div>
.parent {
display: flex;
width: 300px;
height: 200px;
border: 1px solid red;
}
.child {
width: 100px;
height: 100px;
border: 1px solid green;
}
:
As you can see, the total width of our elements is less than the width of the parent, so there is empty space on the right.
If desired, this empty space can be divided proportionally between our elements. This is done using the flex-grow property, which is set on flex items. The value of this property is a unitless number.
Let's see in practice how this property works.
Example
Now we have two flex blocks with a width of 100px. Their total element width is 200px, and the parent width is 300px. It turns out that there is free space of 100px.
If the elements do not have flex-grow, then we will simply see this free space. If they do, then the actual width of the elements will be greater than the specified one - they will proportionally divide the free space between themselves and add it to their width.
For example, let's say the first element has flex-grow equal to 1, and the second element has 3. Let's calculate how much free space each element will receive.
First, we need to get the total number of flex-grow units of all our elements. For the first element, it is 1, and for the second, it is 3. This means that in total it is 4.
Now let's divide 100px of free space by 4 and we get that 25px falls to one unit of flex-grow. It turns out that one unit of flex-grow will be added to the first element, that is 25px, and three units to the second, that is 75px.
The width of the first element will be 125px, and the width of the second element will be 175px:
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
</div>
.parent {
display: flex;
width: 300px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 100px;
flex-grow: 1;
}
.elem2 {
width: 100px;
flex-grow: 3;
}
:
Example
Now let's say the width of the parent is 400px, the width of the first element is 200px, and the width of the second element is 100px. It turns out that the free space is again 100px.
Let's give each element flex-grow, which is 1. That's 2, which is 100px of available space divided by 2. That's 50px per greed unit.
Since all elements have the same value of flex-grow, the same value of 50px will be added to all elements. This means that the first element will become 250px, and the second will become 150px:
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
</div>
.parent {
display: flex;
width: 400px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 200px;
flex-grow: 1;
}
.elem2 {
width: 100px;
flex-grow: 1;
}
:
Example
Let the width of the parent again be 400px, the width of the first element be 200px, and the width of the second element be 100px.
Let's now set the first element's flex-grow to 3, and the second element's to 1. This gives us a total greed of 4. Then one unit of greed is .
100px / 4 = 25px
The first element will have 75px added to it, making it 275px, and the second element will have 25px added to it, making it 125px:
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
</div>
.parent {
display: flex;
width: 400px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 200px;
flex-grow: 3;
}
.elem2 {
width: 100px;
flex-grow: 1;
}
:
Practical tasks
In all of the problems below, you'll be presented with some code with flex items that have a width and flex-grow. Given the code, calculate what sizes each item will have. Then run the code and check your calculations by measuring the actual widths of the items.
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
<div class="child elem3">3</div>
</div>
.parent {
display: flex;
width: 500px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 200px;
flex-grow: 3;
}
.elem2 {
width: 100px;
flex-grow: 1;
}
.elem3 {
width: 100px;
flex-grow: 1;
}
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
<div class="child elem3">3</div>
</div>
.parent {
display: flex;
width: 700px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 100px;
flex-grow: 1;
}
.elem2 {
width: 100px;
flex-grow: 2;
}
.elem3 {
width: 200px;
flex-grow: 3;
}
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
<div class="child elem3">3</div>
</div>
.parent {
display: flex;
width: 500px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 100px;
flex-grow: 1;
}
.elem2 {
width: 100px;
flex-grow: 1;
}
.elem3 {
width: 100px;
flex-grow: 1;
}
<div class="parent">
<div class="child elem1">1</div>
<div class="child elem2">2</div>
<div class="child elem3">3</div>
<div class="child elem4">4</div>
</div>
.parent {
display: flex;
width: 1000px;
height: 200px;
border: 1px solid red;
}
.child {
height: 50px;
border: 1px solid green;
}
.elem1 {
width: 200px;
flex-grow: 1;
}
.elem2 {
width: 100px;
flex-grow: 2;
}
.elem3 {
width: 100px;
flex-grow: 4;
}
.elem4 {
width: 100px;
flex-grow: 3;
}