I recently started The Odin Project and I hit a wall during the FlexBox section. I had a bit of trouble understanding exactly how
flex-basis in particular functioned relative to different
flex-shrink values so after going taking time to go through different resources, I've found a way that helped me understand which is just through a bit of ratio math.
flex-basis - This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword. Default value of
auto which takes width/height instead depending on
flex-direction. If no width/height is set then it uses the content size.
flex-grow - This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up. Default value of 0.
You can think of
flex-basis as a virtual width or the width that the entire flex system sees relative to a particular element. Set a flex-basis of
50px to the fourth element and observe the change.
The boxes are colored along with the container to show you changes in width/increase in available space in container
The 4th box decreases in size by
50px and the available space increases
+50px. It basically put up part of its width as being free to take. If the code were running on your browser natively and you checked the flex section in your developer tools, you would see something like:
Notice how the final size says
50px , comment out the
flex-basis styling and notice it goes back to the set width which is because the default value of
auto and so it defaults to the width of the item.
Now add the
flex-basis styling back and then set a
flex-grow of 1 to the box and observe the changes.
By increasing its
flex-grow, we've given it permission to
grow and essentially take up any
available space . Notice that it takes up the
150px space that is available.
Like before, temporarily comment out
flex-basis and see what changes, this time since it's width is back to
100px , the available space is
100px and it still takes it all. Add the
flex-basis value back.
1 to the 3rd box and observe the changes.
This time the 4th box takes only
75px of space, same goes for the third box. Why? Well, now we gave the 3rd box permission to grow and it will do that. It will want to take a piece out of the available space just like the 4th does. How do they decide how the space is allocated? simply by ratio.
flex-grow values of items in a flex-container as a ratio of how much available space it will get.
Box #1 - 0
Box #2 - 0
Box #3 - 1
Box #4 - 1
free space - 150px
What is listed above is the
flex-grow values for the items in the flex container and the available space in the container. Lets see some simple ratio math.
(0/(0+0+1+1)) * 150px = 0px Box 1 = 100px + 0px.
(0/(0+0+1+1)) * 150px = 0px Box 2 = 100px + 0px.
(1/(0+0+1+1)) * 150px = 75px Box 3 = 100px + 75px
(1/(0+0+1+1)) * 150px = 75px Box 4 = 50px + 75px
Remember Box 4 lost 50px of its width when it set its
As you can see, rather than box 3 and 4 splitting 100px which is the available space by default, they ended up splitting up 150px because has a
50px which you can interpret as having a perceived width(in terms of the entire flex system) of 50px.
If two elements have the same flex-grow value, they will receive the same amount of space from the available space.(in most cases)
Lets spice things up a bit, don't revert any current chances to the css code, give the 1st box a flex basis of
80px and a
1, also give Box 2 a
2. Using the previous approach, you can deduce how much space will be allocated to each element.
Now that Box 1 has a flex-basis of
80px,you can say its adding
20px of its width to the available space. So now the available space becomes
100px + 50px + 20px =
(1/(1+2+1+1)) * 170px = 34px Box 1 = 80px + 34px = 114px
(2/(1+2+1+1)) * 170px = 68px Box 2 = 100px + 68px = 168px
(1/(1+2+1+1)) * 170px = 34px Box 3 = 100px + 34px = 134px
(1/(1+2+1+1)) * 170px = 34px Box 4 = 50px + 34px = 84px
You can see the new width of the boxes, it can be verified through the developer tools or you can set the width of that black box and check it against each of the flex items by moving it around in its container.
Note that if we increased the
flex-basis of an item here higher than its own width, it will increase in width in this flex system. To get the increase in width, just get the difference between its set width and the
flex-basis . If it has a
flex-grow higher than 0, the same ratio approach will still work as long as you realize that the specific item basically
took a chunk out of the available space before the allocation of space to all items begins.