DEV Community

loading...

Keeping the Footer at the Bottom with CSS-Grid

niorad profile image Antonio Radovcic Updated on ・2 min read

Title-Image

At some point in a project, one gets annoyed by the footer hovering right under the header, because there is no content yet to fill up the space. There also may be some really short pages (like the 404), which might not be long enough to fill the whole browser.

Keeping the footer at the browser's bottom just got a little bit easier with CSS-Grid. It's possible to go with some CSS-trickery, Flexbox or JS, but the Grid-solution is the most elegant and simple in my opinion.

Please note that this is only supported in modern browsers, as of this writing. The good thing is, that this method won't break anything for older browsers.

The HTML-Structure will be as follows:

<html>
    <body>
        <article>
            <header>
            </header>
            <main>
            </main>
            <footer>
            </footer>
        </article>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

This is probably a bit simplified in comparison to some real-world-projects. It's important to keep the main content-area (main) and the footer (footer) in the same parent-element.

html, body {
    width: 100%;
    height: 100%;
}

article {
    min-height: 100%;
    display: grid;
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 100%;
}
Enter fullscreen mode Exit fullscreen mode

The important bit is the "grid-template-rows"-property. Here we tell the browser, that we want the first child-element of "article" to be just as high as it naturally is ("auto"). The second should be one fr high, which means it will get as high as possible, since there's no other fr-item in there. The third child will be of natural height. again.

Don't forget to set the html- and body-elements to be of 100% height, or else your grid-container won't fill up the entire browser.

Here's the working example on CodePen.

In case you didn't know: CSS-Grid is now supported on every modern browser. It's a convenient way to define page-layouts and so much more. Go check out Wes Bos' free course on the topic.

EDIT:
You can achieve the same thing with Flexbox. If you need the feature today (Jan 2018), this would be a wider supported way. Check out Dominik Weber's article "Keeping the footer at the bottom with CSS Flexbox"

UPDATE:
Firefox 52 supports Grid, but it's buggy, especially for this case. The elements are not keeping their natural heights. So if you need to support FF52, use the Flexbox-Solution.

Discussion (32)

pic
Editor guide
Collapse
itsbennett profile image
Bennett Mouton

THE POST I'VE BEEN WAITING FOR!! At a site I frequent, at that. And Wes Bos's course is incredible! He makes some really great courses.

Collapse
peter profile image
Peter Kim Frank

Thanks, this is really helpful. I'm sure every beginner dev has had this exact frustrating experience with battling the CSS to make the footer stay put. Really handy.

Collapse
itsbennett profile image
Bennett Mouton

"Wow look at all CSS can do!"

couple minutes later while the high is still kicking

"Err... is this right? Should it be hard to put the footer at the bottom? Lets search Google."

metric boatload of stackoverflow/w3/css-tricks of tutorials

"Oh."

Collapse
andy profile image
Andy Zhao (he/him)

I actually spent 3 hours trying to put the footer down (ha) once...

Nice guide!

Collapse
niorad profile image
Antonio Radovcic Author

Yea it can get really messy. Since flexbox it's kind-of solved, before that you either had to give the main a min-height, or fix the footer-height in px...

Collapse
xaddict profile image
Luuk Lamers

If you’re going to use grid you would probably put that inside of an @supports query.
This means you can also remove the html,body statement and switch min-height:100% for min-height:100vh which takes care of all that in one statement. Cleans up even better 🙂

Collapse
niorad profile image
Antonio Radovcic Author

Grid fails pretty gracefully, so "supports" is not necessarily needed. but the 100vh thing is nice, you can omit the height in body and html that way. thanks!

Collapse
xaddict profile image
Luuk Lamers

In this case it does yeah. But two-dimensional grids can really destroy a page when it isn’t supported. That was the case I was thinking about. I’ve seen it on “forward thinking” sites where there was no progressive enhancement whatsoever

Collapse
giacomosorbi profile image
Giacomo Sorbi

My understanding was that css-grid is recommended when you need to align in two dimensions, whereas flexbox is pretty fine to deal with one dimension.

Browser support is also slightly better for flexbox, not sure about performances.

Collapse
niorad profile image
Antonio Radovcic Author

You can add more columns, of course, e.g. for a sidebar. That's the advantage over flexbox. Grid is great for whole-page-layouts, Flexbox' strength lies more in the smaller scope, like Navs or Lists.

Collapse
giacomosorbi profile image
Giacomo Sorbi

Still would see it as a bit of an overkill for this specific use case and, really, nothing prevents you from using flexbox also in the larger scope of the page.

Thread Thread
niorad profile image
Antonio Radovcic Author

Of course not. I was not stating that.

Collapse
timovn profile image
timo van neerden

Hi,

Thanks for that solution!

Here is a fork of that pen using min-height and positioning, that I usually use : codepen.io/lehollandaisvolant/pen/...

It has the same global behaviour.

Collapse
harlinatwork profile image
Harlin Seritt 🐍 • Edited

Good stuff! I found that I only had to use:

.wrapper {
min-height: 100%;
display: grid;
grid-template-rows: auto 1fr auto;
}

to get this to work for me. The styles for html and body weren't necessary for some reason.

ETA:

I found that if I put in <!DOCTYPE html> at the top, I then had to do:

html, body {
height: 100%;
}

to get this to work. But even then the scrollbars showed up because the footer was then a bit below the page. So, setting the height in the html, body bracket to 99% seemed to do the trick.

Collapse
greggoms profile image
Greg Burton

If you're using Gatsby, you'll have to set #gatsby-focus-wrapper and #___gatsby to 100% height and 100% width as well.

Thanks for this post!

Collapse
linards_berzins profile image
Linards Bērziņš • Edited

hey,

what does that mean exactly. I get the TypeError: when trying to access the project page on the porfolio.

I have not added gatsby-focus-wrapper anywhere in my code

Collapse
greggoms profile image
Greg Burton • Edited

If you’re getting a TypeError then I’m assuming you’re putting this in a .js file. It needs to go inside your .css, unless you’re using a library like styled-components to write css inside a .js file.
This is what you need inside your css:

html,
body,

#gatsby-focus-wrapper,

#___gatsby {

height: 100%;
width: 100%;

}

#gatsby-focus-wrapper and #___gatsby are hidden divs that gatsby injects into the DOM in between the html and body tags.

Think of it like a chain. The chain links include the html, gatsby-focus-wrapper, ___gatsby, and body tags. If you don’t add the height and width properties to all of them (inside your css file), the chain would look incomplete and your footer won’t stay at the bottom.

I hope this wasn’t too confusing!

PS - this site’s auto-markdown syntax is turning everything next to the div id sign “#” into a huge header. Out of my control lol

Thread Thread
linards_berzins profile image
Linards Bērziņš • Edited

Thank you for the reply,

I've added the IDs in my main .scss file on the root.

However Im still getting a weird TypeError when trying to navigate to the portfolio item, that is a component in my GatsbyJS site.

dev-to-uploads.s3.amazonaws.com/i/...

Thread Thread
greggoms profile image
Greg Burton • Edited

It not a weird TypeError. It’s saying “you want me to select the h1 inside of the gatsby-focus-wrapper div but there isn’t one.”

Here’s an example of how the structure should look. See how there’s no h1 anywhere to be seen. My theory without seeing your code is that you’re trying to access an h1 that doesn’t exist.

dev-to-uploads.s3.amazonaws.com/i/...

Thread Thread
linards_berzins profile image
Linards Bērziņš

Thank you,will try this out when time will allow.

Collapse
equinusocio profile image
Mattia Astorino

You can do it with just position: sticky that is the correct way avoiding manipulating the content flow.

Collapse
niorad profile image
Antonio Radovcic Author • Edited

Sounds interesting; to which element would you apply pos:sticky? I only used it with affix-kind-of things like keeping sidebars on screen.

(The post is not about keeping it always on the bottom of the browser, only to push it down if the page isn't filling up the browser.)

Collapse
domysee profile image
Dominik Weber

Great article, doing it with CSS Grid is a really elegant solution.

While reading it, I somehow got the feeling that doing the same with flexbox is complicated. Which it is not.

So I've wrote a kind of answer article, Keeping the footer at the bottom with CSS Flexbox, to explain how it is done with flexbox.

Please don't take this as disrespectful, I just want to show people who cannot use CSS Grid how it is possible to achieve the same with flexbox.

Collapse
niorad profile image
Antonio Radovcic Author

No that's great, I'll link to your article.

Flexbox works great. If I'd need to support more browsers, that's the way to go! (Not looking forward to debugging IE, still...)

I think I skipped that method in prod, because my last two projects (since Flex became widely available) had such ginormous footers that they were bigger than any browser-height anyways ¯_(ツ)_/¯

Collapse
jessemezini profile image
Jesse Mezini

If using a single page application like ReactJS, remember to add width: 100% and height: 100% to the #root too.

Collapse
niorad profile image
Antonio Radovcic Author

Nowhere in your link does it say that, but it doesn't really matter, since it's not what the post is about, anyway.

Collapse
esanctorum profile image
Evandro Santos • Edited

Hey Antonio, nice job I wasn't expecting that, but I've made a little change on your code instead using %, I went for vw and vh... which can be seen here codepen.io/omgitsevan/pen/aqZGBP

Collapse
niorad profile image
Antonio Radovcic Author

That's useful, thanks!

Collapse
esanctorum profile image
Collapse
urakymzhan profile image
Ulan Rakymzhanov

Thanks, this helped me in my project.

Collapse
kitsonbroadhurst profile image
Kitson Broadhurst • Edited

If you're using React add #root to the list with html, body for full width and height 👌