Sunday, December 13, 2020

How to use flex to spread content vertically through all the page

How to use flex to spread content vertically through all the page.

Sometimes we want to have a group of elements that we want to stretch out to fill the whole page, to make it feel filled and balanced.

For the following suggestion, we'll use these elements:

<div class="container">
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</div> 

When thinking about CSS, the first thing that comes to mind is the display: flex; property and in a column direction; so it centers the content and stacks the element on top of each other:

.container {
    display: flex;
    flex-direction: column;
}

/*To make the boxes distinguishable*/
.box {
    margin: 5px;
    border: 1px solid black;
}

However this isn't enough. It renders 3 lines: the black borders of our 3 divs, with 0 height and 100% width, separated by their CSS margin.

To give height to these divs, we need to change 2 things:

First, we need to set the flex-grow for each of the box classed elements. This will allow these divs to grow if needed according to what the parent element wants, and;

Second, we need to set the height of the container. By default, an element will try to take the minimum ammount of size required to accomodate the inner content.

To fill up the whole height of the screen, we need to set the container to take 100% of the height of the parent elements. Unfortunately, the upper element (<body>) doesn't have a height set up, so it defaults to the minimum. So we need to set to 100% the height of the body and of the next up element, the html.

In the end the CSS will look like this:

.container {
    display: flex;
    flex-direction: column;
}
.box {
    margin: 5px;
    border: 1px solid black;
    flex-grow: 1;
}
html, body, .container{
  height: 100%;
}

To sum up, to stretch your content vertically on a webpage, you'll need to set the hight of the container and parent elements to 100%, add display flex to the container element, and have the stretchin child elements the flex-grow.