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

Viewed 225309

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.

31 Answers

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 */
}

You could use position: absolute following to put the footer at the bottom of the page, but then make sure your 2 columns have the appropriate margin-bottom so that they never get occluded by the footer.

#footer {
    position: absolute;
    bottom: 0px;
    width: 100%;
}
#content, #sidebar { 
    margin-bottom: 5em; 
}

Set the CSS for the #footer to:

position: absolute;
bottom: 0;

You will then need to add a padding or margin to the bottom of your #sidebar and #content to match the height of #footer or when they overlap, the #footer will cover them.

Also, if I remember correctly, IE6 has a problem with the bottom: 0 CSS. You might have to use a JS solution for IE6 (if you care about IE6 that is).

Since the Grid solution hasn't been presented yet, here it is, with just two declarations for the parent element, if we take the height: 100% and margin: 0 for granted:

html, body {height: 100%}

body {
  display: grid; /* generates a block-level grid */
  align-content: space-between; /* places an even amount of space between each grid item, with no space at the far ends */
  margin: 0;
}

.content {
  background: lightgreen;
  /* demo / for default snippet window */
  height: 1em;
  animation: height 2.5s linear alternate infinite;
}

footer {background: lightblue}

@keyframes height {to {height: 250px}}
<div class="content">Content</div>
<footer>Footer</footer>

The items are evenly distributed within the alignment container along the cross axis. The spacing between each pair of adjacent items is the same. The first item is flush with the main-start edge, and the last item is flush with the main-end edge.

Just invented a very simple solution that worked great for me. You just wrap all page content except for the footer within in a div, and then set the min-height to 100% of the viewpoint minus the height of the footer. No need for absolute positioning on the footer or multiple wrapper divs.

.page-body {min-height: calc(100vh - 400px);} /*Replace 400px with your footer height*/

div.fixed {
   position: fixed;
   bottom: 0;
   right: 0;
   width: 100%;
   border: 3px solid #73AD21;
}
<body style="height:1500px">

   <h2>position: fixed;</h2>

   <p>An element with position: fixed; is positioned relative to the viewport, which means it always stays in the same place even if the page is scrolled:</p>

   <div class="fixed">
      This div element has position: fixed;
   </div>

</body>

If you don't want it using position fixed, and following you annoyingly on mobile, this seems to be working for me so far.

html {
    min-height: 100%;
    position: relative;
}

#site-footer {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    padding: 6px 2px;
    background: #32383e;
}

Just set the html to min-height: 100%; and position: relative;, then position: absolute; bottom: 0; left: 0; on the footer. I then made sure the footer was the last element in the body.

Let me know if this doesn't work for anyone else, and why. I know these tedious style hacks can behave strangely among various circumstances I'd not thought of.

On my sites I always use:

position: fixed;

...in my CSS for a footer. That anchors it to the bottom of the page.

For me the nicest way of displaying it (the footer) is sticking to the bottom but not covering content all the time:

#my_footer {
    position: static
    fixed; bottom: 0
}

The flex solutions worked for me as far as making the footer sticky, but unfortunately changing the body to use flex layout made some of our page layouts change, and not for the better. What finally worked for me was:

    jQuery(document).ready(function() {

    var fht = jQuery('footer').outerHeight(true);
    jQuery('main').css('min-height', "calc(92vh - " + fht + "px)");

});

I got this from ctf0's response at https://css-tricks.com/couple-takes-sticky-footer/

REACT-friendly solution - (no spacer div required)

Chris Coyier (the venerable CSS-Tricks website) has kept his page on the Sticky-Footer up-to-date, with at least FIVE methods now for creating a sticky footer, including using FlexBox and CSS-Grid.

Why is this important? Because, for me, the earlier/older methods I used for years did not work with React - I had to use Chris' flexbox solution - which was easy and worked.

Below is his CSS-Tricks flexbox Sticky Footer - just look at the code below, it cannot possibly be simpler.

(The (below) StackSnippet example does not perfectly render the bottom of the example. The footer is shown extending past the bottom of the screen, which does not happen in real life.)

html,body{height: 100%;}
body     {display:flex; flex-direction:column;}
.content {flex: 1 0 auto;} /* flex: grow / shrink / flex-basis; */
.footer  {flex-shrink: 0;}

/* ---- BELOW IS ONLY for demo ---- */
.footer{background: palegreen;}
<body>
  <div class="content">Page Content - height expands to fill space</div>
  <footer class="footer">Footer Content</footer>
</body>

Chris also demonstrates this CSS-Grid solution for those who prefer grid.


References:

CSS-Tricks - A Complete Guide to Flexbox

Have a look at http://1linelayouts.glitch.me/, example 4. Una Kravets nails this problem.

This creates a 3 layer page with header, main and footer.

-Your footer will always stay at the bottom, and use space to fit the content;

-Your header will always stay at the top, and use space to fit the content;

-Your main will always use all the available remaining space (remaining fraction of space), enough to fill the screen, if need.

HTML

<div class="parent">
  <header class="blue section" contenteditable>Header</header>
  <main class="coral section" contenteditable>Main</main>
  <footer class="purple section" contenteditable>Footer Content</footer>
</div>
    

CSS

.parent {
  display: grid;
  height: 95vh; /* no scroll bars if few content */
  grid-template-rows: auto 1fr auto;
}
    

A quick easy solution by using flex

  • Give the html and body a height of 100%
html,
body {
  width: 100%;
  height: 100%;
}
  • Display the body as flex with column direction:
body { 
  min-height: 100%;
  display: flex;
  flex-direction: column;
}
  • Add flex-grow: 1 for the main
main {
  flex-grow: 1;
}

flex-grow specifies how much of the remaining space in the flex container should be assigned to the item (the flex grow factor).

*, 
*::after,
*::before{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html,
body {
  width: 100%;
  height: 100%;
}

body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

main {
  flex-grow: 1;
}

footer{
  background-color: black;
  color: white;
  padding: 1rem 0;
  display: flex; 
  justify-content: center;
  align-items: center;
}
<body> 
    <main>
        <section >
            Hero
        </section>
    </main>

    <footer >
        <div>
            <p > &copy; Copyright 2021</p>
        </div>
    </footer>
</body>

Keeping your <main> as min-height 90vh will solve your problem forever. Here is the base structure that will help you follow semantics and cover entire page.

Step 1: Keep everything inside the main tag except the header and footer.

<body>
    <header>
        <!╌ nav, logo ╌> 
    </header>
    <main>
        <!╌ section and div ╌> 
    </main>
    <footer>
        <!╌ nav, logo ╌>
    </footer>
</body>

Step 2: Add min-height: 90vh for main

main{
    min-height: 90vh;
}

Usually, header and footer are 70px minimum in height so this case works well, tried and tested!

Try putting a container div (with overflow:auto) around the content and sidebar.

If that doesn't work, do you have any screenshots or example links where the footer isn't displayed properly?

Related