Categories
css footer html sticky-footer

How do you get the footer to stay at the bottom of a Web page?

338

I have a simple 2-column layout with a footer that clears both the right and left div in my markup. My problem is that I can’t get the footer to stay at the bottom of the page in all browsers. It works if the content pushes the footer down, but that’s not always the case.

2

  • I’ll add to @Jimmy: You also need to have to declare absolute (or relative) positioning to the element that contains the footer. In your case, it’s the body element. Edit: I tested it on your page with firebug and it seemed to work very well…

    – yoavf

    Sep 3, 2008 at 19:51


  • may be yo need to stretch the html-page-to-full-height as this link says: makandracards.com/makandra/…

    – sina

    Jun 3, 2020 at 14:32

209

To get a sticky footer:

  1. Have a <div> with class="wrapper" for your content.

  2. Right before the closing </div> of the wrapper place the
    <div class="push"></div>.

  3. Right after the closing </div> of the wrapper place the
    <div class="footer"></div>.

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

7

  • 4

    @jlp: You need to add the form tag to the height:100% statement, else it will break the sticky footer. Like this: html, body, form {height: 100%;}

    Mar 9, 2012 at 13:21

  • I noticed that adding padding to the footer screws it, but figured out that that can be fixed by subtracting the extra padding on the footer from the {footer, push} height.

    – ichigolas

    Oct 20, 2012 at 7:13


  • 1

    The detailed explanation with the demo is provided in this site: CSS Sticky Footer

    – mohitp

    Mar 22, 2013 at 9:15


  • Hey I followed your steps and it works pretty well for big pages. But on small pages where the user is not able to scroll down the footer is a little to far at the bottom. So it makes a nearly empty page scrollable. Anyone knows how to fix this? You can see my test page here sheltered-escarpment-6887.herokuapp.com

    – Syk

    Dec 30, 2015 at 15:03


  • 1

    @Syk I’ve found that reducing the min-height helps. 94% is an ok value, but you still see the issue on mobile 🙁 Not sure there’s a real solution here.

    Nov 16, 2016 at 6:14

107

Use CSS vh units!

Probably the most obvious and non-hacky way to go about a sticky footer would be to make use of the new css viewport units.

Take for example the following simple markup:

<header>header goes here</header>
<div class="content">This page has little content</div>
<footer>This is my footer</footer>

If the header is say 80px high and the footer is 40px high, then we can make our sticky footer with one single rule on the content div:

.content {
    min-height: calc(100vh - 120px);
    /* 80px header + 40px footer = 120px  */
}

Which means: let the height of the content div be at least 100% of the viewport height minus the combined heights of the header and footer.

That’s it.

* {
    margin:0;
    padding:0;
}
header {
    background: yellow;
    height: 80px;
}
.content {
    min-height: calc(100vh - 120px);
    /* 80px header + 40px footer = 120px  */
    background: pink;
}
footer {
    height: 40px;
    background: aqua;
}
<header>header goes here</header>
<div class="content">This page has little content</div>
<footer>This is my footer</footer>

… and here’s how the same code works with lots of content in the content div:

* {
    margin:0;
    padding:0;
}
header {
    background: yellow;
    height: 80px;
}
.content {
    min-height: calc(100vh - 120px);
    /* 80px header + 40px footer = 120px  */
    background: pink;
}
footer {
    height: 40px;
    background: aqua;
}
<header>header goes here</header>
<div class="content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.
</div>
<footer>
    This is my footer
</footer>

NB:

1) The height of the header and footer must be known

2) Old versions of IE (IE8-) and Android (4.4-) don’t support viewport units. (caniuse)

3) Once upon a time webkit had a problem with viewport units within a calc rule. This has indeed been fixed (see here) so there’s no problem there. However if you’re looking to avoid using calc for some reason you can get around that using negative margins and padding with box-sizing –

Like so:

* {
    margin:0;padding:0;
}
header {
    background: yellow;
    height: 80px;
    position:relative;
}
.content {
    min-height: 100vh;
    background: pink;
    margin: -80px 0 -40px;
    padding: 80px 0 40px;
    box-sizing:border-box;
}
footer {
    height: 40px;
    background: aqua;
}
<header>header goes here</header>
<div class="content">Lorem ipsum 
</div>
<footer>
    This is my footer
</footer>

6

  • 5

    This is pretty much the best solution I’ve seen here, worked even in my strange case with some contents of the .content overflowing into the footer for who-knows-what-reason. And I guess that with sth like Sass and variables, it could be ever more flexible.

    Dec 5, 2014 at 20:16

  • 1

    Indeed, this one works like a charm. Easy to fallback for a non-supporting browsers too.

    – Aramir

    Jul 3, 2015 at 23:06

  • 3

    How is messing with absolute measurements not still hacky? At best it’s perhaps less hacky

    – Jonathan

    Mar 9, 2016 at 9:33


  • But and if the height of footer and header is mensured in percent and not px? Like 15% of the page’s height?

    Apr 27, 2017 at 2:36

  • 4

    Viewport units don’t always work as expected on mobile browsers that hide or show address bar depending on scroll position

    – Evgeny

    Apr 28, 2017 at 15:33

78

Sticky footer with display: flex

Solution inspired by Philip Walton’s sticky footer.

Explanation

This solution is valid only for:

  • Chrome ≥ 21.0
  • Firefox ≥ 20.0
  • Internet Explorer ≥ 10
  • Safari ≥ 6.1

It is based on the flex display, leveraging the flex-grow property, which allows an element to grow in either height or width (when the flow-direction is set to either column or row respectively), to occupy the extra space in the container.

We are going to leverage also the vh unit, where 1vh is defined as:

1/100th of the height of the viewport

Therefore a height of 100vh it’s a concise way to tell an element to span the full viewport’s height.

This is how you would structure your web page:

----------- body -----------
----------------------------

---------- footer ----------
----------------------------

In order to have the footer stick to the bottom of the page, you want the space between the body and the footer to grow as much as it takes to push the footer at the bottom of the page.

Therefore our layout becomes:

----------- body -----------
----------------------------

---------- spacer ----------
                             <- This element must grow in height
----------------------------

---------- footer ----------
----------------------------

Implementation

body {
    margin: 0;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.spacer {
    flex: 1;
}

/* make it visible for the purposes of demo */
.footer {
    height: 50px;
    background-color: red;
}
<body>
    <div class="content">Hello World!</div>
    <div class="spacer"></div>
    <footer class="footer"></footer>
</body>

You can play with it at the JSFiddle.

Safari quirks

Be aware that Safari has a flawed implementation of the flex-shrink property, which allows items to shrink more than the minimum height that would be required to display the content.
To fix this issue you will have to set the flex-shrink property explicitly to 0 to the .content and the footer in the above example:

.content {
  flex-shrink: 0;
}

.footer {
  flex-shrink: 0;
}

Alternatively, change the flex style for the spacer element into:

.spacer {
  flex: 1 0 auto;
}

This 3-value shorthand style is equivalent to the following full setup:

.spacer {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: auto;
}

Elegantly works everywhere.

7

  • 20

    I feel this is the correct answer, since it’s actually the only approach which works even when the height of the footer is not known.

    – fstanis

    Aug 21, 2016 at 0:19

  • This messes up the grid with Neat 2

    – Halfacht

    Mar 16, 2018 at 12:13

  • But why not the Philip Walton’s solution itself, why an extra “spacer” element?

    – YakovL

    Apr 19, 2018 at 23:04

  • 1

    @YakovL In Walton’s solution .Site-content element plays the same role as spacer. It’s just called differently.

    – Gherman

    Nov 29, 2019 at 15:18

  • @Gherman well, .Site-content has an analog .content in this markup.. but nevermind, I asked for the case gcedo has some specific idea about it, no need to guess

    – YakovL

    Nov 29, 2019 at 15:24