DEV Community 👩‍💻👨‍💻

Dominik Weber
Dominik Weber

Posted on • Updated on

Keeping the footer at the bottom with CSS Flexbox

Just now I've read the post Keeping the Footer at the Bottom with CSS-Grid.
While reading, I somehow got the impression that doing the same with 'just' flexbox is difficult. It's not.

This is not to belittle the referenced post in any way, it is very well explained, and in my opinion more elegant than with flexbox. I just want to explain that it is as easy with flexbox as it is with grid, so that if, for whatever reason, you cannot use grid, you don't shy away from implementing it with flexbox.

I'll use the same HTML as in the referenced article:

Enter fullscreen mode Exit fullscreen mode

And here the CSS to put the footer at the bottom, where it belongs:

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

article {
    min-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: stretch;

main {
    flex-grow: 1;

header, main, footer {
    flex-shrink: 0;

Enter fullscreen mode Exit fullscreen mode

On the container, we set flexbox to align the contents in a column. The elements should stretch so that they span the whole width, and not just the width their contents take up.

Setting flex-grow: 1 on main makes it grow to fill the available space. This puts the footer at the bottom, since main takes up all the space in the middle.

The use for flex-shrink: 0 is probably less obvious, and it is often forgotten. At least I forgot it way more often than I'd like to admit.

By default, flex-shrink is set to 1. This makes the items shrink if there is not enough space, which happens if the content is larger than the screen. The results can look very weird, e.g. a button that is smaller than the text it contains. Setting it to 0 stops that behavior.

That's it. That's everything you need to know to position the footer at the bottom with flexbox. :)

Follow me on Twitter for more of my thoughts, articles, projects and work.

Top comments (17)

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!

leanferret profile image
Björn Biege

Instead of 100% height on body and html it would be better to set just body to min-height: 100vh.
100% height on html can break your content rendering with background images, or some other effects because the longer content flows out of the html area if you have to scroll down.. :)

pyrax profile image
Björn Clees • Edited on

Unfortunately, min-height: 100vh has a problem as well: on mobile browsers (e.g. Chrome) viewport height does not consider if the address bar is shown or not. So, when address bar is expanded, it will cause an y-overflow with this sticky footer solution even though your content would fit on page (because it ends up with address-bar-height + 100vh).

Best solution for me has, so far, been to use the grid solution if browser support is not a concern or make your design work without a sticky footer.

leanferret profile image
Björn Biege

Oh ok. I didn't think about that. But now i see.
Yes Grid is nice and solves many problems. :)

robertogongora profile image
Roberto Gongora

I do this on all my websites! I just watched the whole CSS Grids for Everyone by Wes Bos and I'm excited to adopt CSS Grids from now on.

What I'd be super interested in, though, would be a list of examples of what you can do in Flexbox that you can't do with CSS Grids and viceversa. I know certain things like reversing the order of a list is "impossible" in CSS Grid due to how it works, but real world examples would be cool!

I'll try to make my own list while I'm working too in case I never find such a post, but I think it's a cool idea.

webdeb_wms profile image
WMS Web & Marketing Strategist

I agree, but I've stumbold with a few cons. For example, when you put dynamic Adsense inventory, the grid causes hell because it doesn't allow the containers tu expand automatically, so you end up with ads overlaying the rest of the content.

drwebmagazin profile image
Dr. Web • Edited on


flex-direction: column;
align-items: stretch;

snippet saved my day. Thank you for that! I used it on our agency directory site [WIP] to keep the buttons at the bottom of the equal height cards.

wptechprodigy profile image
Waheed Afolabi

Thanks, it worked!

sweeptic profile image

not a good solution - if the 'main' content is more than 100% (lorem2000) then the height of the html box will remain only 100%. if the whole page fits on one page then I think it's okay.

leanferret profile image
Björn Biege • Edited on

A solution for this would be using min-height: 100vh on body and do nothing on html :)

smak1n profile image

life saver , thank you!

eshamittal profile image

The footer is working okay on other pages but it's not working on main page. Can you tell me what to do? Only main page is showing the difference in footer and bottom. Other pages are working okay

tdekoekkoek profile image
Trevor de Koekkoek

This is so nice and simple. I tried so many other things that only half worked. There was always one scenario that didn't work. This works for me in modal dialogs as well as full screen. Thanks!

webdeb_wms profile image
WMS Web & Marketing Strategist

This is undoubtedly the most accurate, detailed and well structured explanation I've seen.
Thank you Dominik for sharing your knowledge.

vikas profile image
Vikas Kumar

How to handle mobile view where keyboard pushes the footer up over another element.

thomaskanzig profile image
Thomas Känzig

Really good article.

skunshd profile image

Thank you! Here is a codesandbox implementation of your code

An Animated Guide to Node.js Event Lop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.