Flexbox: How to make content take up remaining space after fixed sidebar

It's a classic scenario. You have a sidebar, and you have content. They are getting in the way of each other, and float: left isn't going to cut it.

Flexbox was made for this kind of thing!

To begin, find the common element that contains both your sidebar and your content. Give it the following styling so that the elements within can make use of Flexbox rules.

display: flex;

As a general rule, when it comes to Flexbox, parent elements do not own the styles of their children. Elements tend to own their own styles.

Step 1 - Fix your sidebar!

Make sure you are applying this style to an element directly below the one with display: flex on it.

This is a use case for flex-basis.

flex-basis is a little hard to describe without introducing its siblings: flex-grow and flex-shrink. flex-basis is the width (or height for column scenarios) that an element will take before it makes the decision to grow or shrink. It is the basis for flex behaviour.

flex-grow and flex-shrink define how the element may change in size relative to the basis it has. In this case, we can guess what we want for these values. Zero! We want the sidebar to be a particular size and to not grow or shrink. What this means is that we can ignore these attributes entirely; they will default to 0 if not specified.

In the end, all we need to do is give our css this line:

flex-basis: 20%;

(The 20% can be 200px, 20vw, whatever you want it to be).

You can also make use of the flex attribute, defining it like so:

flex: 0 0 20%;

This is shorthand, defining respectively flex-grow, flex-shrink and flex-basis. Using flex: 20% will also set your flex-basis to 20%. However, it will default your flex-grow and flex-shrink to values of 1, resulting in automatic shrinking or growing depending on the circumstances.

By the way, if you say flex-basis: auto it means that flex-basis should refer to the element's width or height property, whichever is relevant.

Part 2 - Stretch your content!

Now, here is a use case for flex-grow, or flex, depending on your preference.

In this case, you don't care how big or small your content is. Given the fixed size of your sidebar, you simply know that you want your content to take up all remaining space in the container. This means you don't need to specify a flex-basis at all. To explain this, I will need to explain how flex-grow works.

The value you give to flex-grow is used as a proportion. All elements under the display: flex container have to share the space that it contains. Each element will take up its flex-basis and then will use flex-grow to divide up what is left and decide who is really the favourite child.

If you have multiple elements all with flex-grow: 1, then they will evenly distribute what is left. If you have three elements, two with flex-grow: 1 and one with flex-grow: 2 then you will find the first two taking quarters and the last taking a half. Basically an element with a flex-grow value will take up its own value as a proportion of the sum of all flex-grow values within the same flex container.

In this case, the sidebar has a flex-grow value of 0. This means it gets no cut of the space remaining after flex-basis has had its way. The result is that if we give the content element a flex-grow value of 1, we are telling it that it can take up 100% of the remaining space. This is because it has no competition.

flex-grow: 1;

However, specifying it this way is considered somewhat bad practice. It is preferable to use the flex attribute if possible. Instead we can write:

flex: 1;

Which is equivalent to:

flex: 1 1 0%;

As previously stated, this means flex-grow and flex-shrink are both 1, and flex-basis is 0% (as we wanted). But what's with this flex-shrink: 1 business?

In the same way that flex-grow allowed the content element to take up remaining space after flex-basis has its way, what if there isn't enough room in the element to contain the sum of all flex-basis values? Then something will have to shrink, and flex-shrink will decide the proportion at which elements reduce their size. This isn't necessarily needed here, but for more advanced sidebars, you could easily envision a scenario where flex-shrink could come in handy.

Demonstration

Screenshot 2020-09-24 234219.jpg

Screenshot 2020-09-24 234254.jpg

Sorry about these screenshots lol. Anyway, happy coding!

Dinys Monvoisin's photo

I read the article and still hard for me to understand the difference between flex-basis, flex-grow and flex-shrink. Could you better explain it?

Luke Household's photo

I would put it this way.

flex-basis is describing the original widths of the elements. If the combined width of all the elements is smaller than the available space, flex-grow becomes relevant. Elements will grow by an amount based on the proportion between their flex-grow value and the sum of all the flex-grow values. If the combined width of all the elements is larger than the available space, the elements will shrink by an amount based on the proportion between their flex-shrink value and the sum of all flex-shrink values.

There's no way for flex-grow and flex-shrink to be used at the same time. You can only know how much an element will grow or shrink by knowing the relevant values of all the neighbour elements.

Hope this is helpful!

Neyla Laximir's photo

A great tool for content developers involves how to monetize their content. I found out about MintMe, where I can share special content with my supporters and allowed me to create my own token, also has just released its version 1.2 with many improvements, so it's amazing.