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>
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%;
}
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.
Oldest comments (32)
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.
"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."
I actually spent 3 hours trying to put the footer down (ha) once...
Nice guide!
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...
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.
You can do it with just position: sticky that is the correct way avoiding manipulating the content flow.
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.)
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.
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 ¯_(ツ)_/¯
Nowhere in your link does it say that, but it doesn't really matter, since it's not what the post is about, anyway.
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
That's useful, thanks!
cheers
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 🙂
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!
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
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.
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.
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.
Of course not. I was not stating that.
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.