Understanding flex-basis and flex-grow
Tags: webdev, beginners, programming, css
Published: 2021-12-03 01:49:06

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-grow` and `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.

## Terminologies

`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.

{% codepen https://codepen.io/truepadawan/pen/yLzBvzZ %}

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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k27ijeppv1gvcvvs9brb.png)

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 `flex-basis` is `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.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vvc9prqrohaj7bqhbfoo.png)

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.

Set a `flex-grow` of `1` to the 3rd box and observe the changes.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rk0t65ph2cxxr81urdn.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cyhn0mtwxajdck8fhpmi.png)

 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.

Assume the `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.

### Box #1

`(0/(0+0+1+1)) * 150px = 0px` Box 1 = 100px + 0px.

### Box #2

`(0/(0+0+1+1)) * 150px = 0px` Box 2 = 100px + 0px.

### Box #3

`(1/(0+0+1+1)) * 150px = 75px` Box 3 = 100px + 75px

### Box #4

`(1/(0+0+1+1)) * 150px = 75px` Box 4 = 50px + 75px

> Remember Box 4 lost 50px of its width when it set its `flex-basis` to 50px
> 

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 `flex-basis` of `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 `flex-grow` of `1`, also give Box 2 a `flex-grow` of `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` = `170px`

### Box #1

`(1/(1+2+1+1)) * 170px = 34px` Box 1 = 80px + 34px = 114px

### Box #2

`(2/(1+2+1+1)) * 170px = 68px` Box 2 = 100px + 68px = 168px

### Box #3

`(1/(1+2+1+1)) * 170px = 34px` Box 3 = 100px + 34px = 134px

### Box #4

`(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.

![Flex Info](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbpo5mi7zpghukutt3gr.png)
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7mi58xfe7mvbab8bw3jp.png)
 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g66r76fcuberr7tu5qm0.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z12hxovd53le9mmacvr7.png)

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.