Sticky footer with Flexbox

by Caryn Humphreys on September 25, 2015

So you’ve got body content and a footer. Unfortunately you’ve got a page that contains a small amount of content, and you notice your footer floating part way up the page. Gross!

Negative Margin Solution

Here’s the traditional way to tackle this, shown by Chris Coyier:

See the Pen Sticky Footer by Chris Coyier (@chriscoyier) on CodePen.

Here’s the markup:

<div class="page-wrap">

    <h1>Sticky Footer</h1>
    <h2>with Fixed Footer Height</h2>

    <button id="add">Add Content</button>  

</div>

<footer class="site-footer">
    I'm the Sticky Footer.
</footer>

First, your html height has to be defined to take up the space available:

html, body {
    height: 100%;
}

To make room for your footer using this solution, you need to make a container with room at the bottom of it for your footer:

.page-wrap {
    min-height: 100%;
    /* equal to footer height */
    margin-bottom: -142px;
}   

.page-wrap:after {
    content: "";
    display: block;
}

Then you can define your footer so that it will sit within the space you’ve made:

.site-footer, .page-wrap:after {
    /* .push must be the same height as footer */
    height: 142px; 
}

This solution certainly will work (as you can see in the result above), but let’s take a look at how flexbox can tackle this.

Flexbox Solution

I have used the negative margin solution in the past but I was curious to see if there was a more elegant solution that required less modifications to the markup and less risk for responsive designs.

See the Pen Sticky footer with flexbox by Caryn Humphreys (@ladycarni) on CodePen.


So we’ve got our basic markup:

<div class="container">
    <div class="main">
        Body Content
    </div>
    <div class="footer">
        Footer Content
    </div>
</div>

First we need to make sure our html is taking up the full height:

html, body {
    height: 100%;
}

Now we need to put a flex on the container around what will hold the content of the entire site. flex-direction establishes the main-axis, which will in turn define the direction its children are laid out in within the flex container. Flexbox allows us to do single-direction layouts. You can think of flex items as primarily laying out either in horizontal rows or vertical columns. What we want here is the column direction, which will fill the available space, from top to bottom.

.container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.

Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).

Once we’ve put the display: flex on the container, we can tell our main div to fill the available space down to the div after it; our footer.

.main {
    background: #333;
    flex: 1;
}
The following two tabs change content below.

Caryn Humphreys

UX Designer
Caryn is a Product Designer. She likes writing about CSS tricks she's discovered, Best UX Practices, living and working in a startup community, and fostering a badass team culture.

Latest posts by Caryn Humphreys (see all)