CSS to make HTML page footer stay at bottom of the page with a minimum height, but not overlap the page

Viewed 1548064

I have the following page (deadlink: http://www.workingstorage.com/Sample.htm ) that has a footer which I can't make sit at the bottom of the page.

I want the footer to

  • stick to the window bottom when the page is short and the screen is not filled, and
  • stay at the document end and move down as normal when there is more than a screenful of content (instead of overlapping the content).

The CSS is inherited and befuddles me. I can't seem to change it properly to put a minimum height on the content or make the footer go to the bottom.

37 Answers

Below are 4 different methods of mine:

In each example the texts are freely-editable to illustrate how the content would render in different scenarios.


1) Flexbox

body{ height:100vh; margin:0; }

header{ min-height:50px; background:lightcyan; }
footer{ min-height:50px; background:PapayaWhip; }

/* Trick */
body{ 
  display:flex; 
  flex-direction:column; 
}

footer{
  margin-top:auto; 
}
<body>
  <header contentEditable>Header</header>
  <article contentEditable>Content</article>
  <footer contentEditable>Footer</footer>
</body>


2) Grid

body{ 
  min-height: 100vh; 
  margin: 0; 
  
  display: grid;
  grid-template-rows: auto 1fr auto;
}

header{ 
  min-height:50px;
  background:lightcyan; 
}

footer{ 
  min-height:50px; 
  background:PapayaWhip; 
}
<body>
  <header contentEditable>Header</header>
  <article contentEditable>Content</article>
  <footer contentEditable>Footer</footer>
</body>


This method below uses a "trick" by placing an ::after pseudo-element on the body, and set it to have the exact height of the footer, so it will occupy the exact same space the footer does, so when the footer is absolute positioned over it, it would appear like the footer is really taking up space and eliminate the negative affects of it's absolute positioning (for example, going over the body's content)

3) position:absolute (no dynamic footer height)

body{ min-height:100vh; margin:0; position:relative; }
header{ min-height:50px; background:lightcyan; }
footer{ background:PapayaWhip; }

/* Trick: */
body {
  position: relative;
}

body::after {
  content: '';
  display: block;
  height: 50px; /* Set same as footer's height */
}

footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 50px;
}
<body>
  <header contentEditable>Header</header>
  <article contentEditable>Content</article>
  <footer contentEditable>Footer</footer>
</body>


4) Table-layout

html{ height:100%; }
body { min-height:100%;  margin:0; }

header {
  height: 50px;
  background: lightcyan;
}

article { 
  height: 1%;
}

footer {
  height: 50px;
  background: PapayaWhip;
}

/**** Trick: ****/

body {
  display: table;
  width: 100%; 
}

body > footer {
   display: table-row;
}
<body>
  <header contentEditable>Header</header>
  <article contentEditable>Content</article>
  <footer contentEditable>Footer</footer>
</body>

A simple method is to make the body 100% of your page, with a min-height of 100% too. This works fine if the height of your footer does not change.

Give the footer a negative margin-top:

footer {
    clear: both;
    position: relative;
    height: 200px;
    margin-top: -200px;
}

Keep the footer at the bottom by using Flexbox

<div style="min-height:100vh; display:flex; flex-direction:column; 
            justify-content:space-between;">
 
     <div> <!-- Wrapper (Without footer) -->
   
        <header>
         I am a header.
        </header>
  
        <article>
        I am an article!
        </article>
   
    </div> <!-- End: Wrapper (Without footer) -->
 
 
     <footer>
     I am a footer.
     </footer>
 
</div>

Note

  • Make sure that you are wrapping everything in a <div> or any other block-level element with the following CSS styles: min-height:100vh; display:flex; flex-direction:column; justify-content:space-between; .

  • Make sure that you are wrapping everything but the footer element in a <div> or any other block-level element.

  • Make sure that you using <footer> or any other block-level element to wrap the footer.

Code Explanation

  • min-height: 100vh ensures that the body element will stretch to at least the full height of the screen

  • flex-direction: column keeps the behavior of normal document flow in terms of retaining stacked block elements (which assumes direct children of the body are all indeed block elements).

  • justify-content:space-between pushes the footer to the bottom of the screen.


Check out how to do the same (Keeping the footer at the bottom) by using Bootstrap 5 - Link

This is known as a sticky footer. A google search for it comes up with a lot of results. A CSS Sticky Footer is the one I've used successfully. But there are more.

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -4em;
}
.footer, .push {
    height: 4em;
}
<html>
    <head>
        <link rel="stylesheet" href="layout.css" ... />
    </head>
    <body>
        <div class="wrapper">
            <p>Your website content here.</p>
            <div class="push"></div>
        </div>
        <div class="footer">
            <p>Copyright (c) 2008</p>
        </div>
    </body>
</html>

Source for this code

footer {
  margin-top:calc(5% + 60px);
}

This works fine

Works for me.

#container{ 
  height:100vh; 
  margin:0; 
  display:flex; 
  flex-direction:column; 
}

#footer{
  margin-top:auto; 
}


<div id="container">
   <div id="header">header</div>
   <div id="body">body</div>
   <div id="footer">footer</div>
</div>

#container{ 
  height:100vh; 
  margin:0; 
  display:flex; 
  flex-direction:column; 
}

#footer{
  margin-top:auto; 
}
<div id="container">
   <div id="header">header</div>
   <div id="body">body</div>
   <div id="footer">footer</div>
</div>

I just answered as similar question in here:

Position footer at bottom of page having fixed header

I'm pretty new at web development, and I know this has been answered already, but this is the easiest way I found to solve it and I think is somehow different. I wanted something flexible because the footer of my web app has a dynamic height, I ended up using FlexBox and a spacer.

  1. Start by setting the height for your html and body
html, body {
    height: 100%;
    display: flex;
    flex-direction: column;
    margin: 0px;
}

I'm assuming a column behavior for our app, in the case you need to add a header, hero or any content vertically aligned.

  1. Create the spacer class
.spacer {
    flex: 1; 
}
  1. So later on your HTML could be something like
<html>
  <body>
    <header> Header </header>
    Some content...
    <div class='spacer'></div>
    <footer> Footer </footer>
  </body>
</html>

You can play with it here https://codepen.io/anon/pen/xmGZQL

I achieved that using CSS grid, basically I defined 3 rows:

  • Header
  • content
  • footer

And the used grid to define the sizes, the trick is to align the footer at the end of the row, like this:

CSS

body {
    display: grid;
    grid-template-rows: auto auto auto;
}

footer {
    display: grid;
    align-self: end; /* The trick */
}

HTML file

<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>

<body>
  <header>
    Header content
  </header>
  
  <h1>main body</h1>
  <p>This is a paragraph.</p>
  
  <footer>
    <p>Hello there.</p>
  </footer>
</body>
</html>

You can use more rows but remember to add the to the CSS, or wrap everything inside a div.

This guide here really helped me figure this out.

ONE line solution using Bootstrap

Apart from all the CSS and jQuery solutions provided,
I have listed a solution using Bootstrap with a single class declaration on body tag: d-flex flex-column justify-content-between

  • This DOES NOT require knowing the height of the footer ahead of time.
  • This DOES NOT require setting position absolute.
  • This WORKS with dynamic divs that overflow on smaller screens.

html, body {
  height: 100%;
}
<html>

    <head>
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    </head>

    <body class="d-flex flex-column justify-content-between text-white text-center">

        <header class="p-5 bg-dark">
          <h1>Header</h1>
        </header>
        <main class="p-5 bg-primary">
          <h1>Main</h1>
        </main>
        <footer class="p-5 bg-warning">
          <h1>Footer</h1>
        </footer>

        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
    </body>

</html>

I consider you can set the main content to viewport height, so if the content exceeds, the height of the main content will define the position of the footer

* {
  margin: 0;
  padding: 0;
  width: 100%;
}

body {
  display: flex;
  flex-direction: column;
}

header {
  height: 50px;
  background: red;
}

main {
  background: blue;
  /* This is the most important part*/
  height: 100vh; 
  
}
footer{
  background: black;
  height: 50px;
  bottom: 0;
}
<header></header>
<main></main>
<footer></footer>

You need to use position: absolute; this is important, then bottom:0

.footer {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}

You can do this

.footer {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  padding: 1rem;
  text-align: center;
}

Position fixed with bottom, left, and right set to 0 works best for me:

.footer {    
    position: fixed;
    background : #d1ccc0;
    bottom : 0;
    left : 0;
    right : 0;
    height : 50px;
}

Position absolute doesn't stick to the bottom, but fixed does.

While I found many similar answers, the only solution that I could find where the footer was always at the bottom and did not display over the existing data was the following:

footer {
    position: relative;
    clear: both;
}

Just customize the footer section

.footer 
{
   position: fixed;
   bottom: 0;
   width: 100%;
   padding: 1rem;
   text-align: center;
}
 <div class="footer">
   Footer is always bootom
 </div>
<!DOCTYPE html>

<html>
 <head>
   <link rel="stylesheet" type="text/css" href="main.css" />
 </head>

<body>
 <div id="page-container">
   <div id="content-wrap">
     <!-- all other page content -->
   </div>
   <footer id="footer"></footer>
 </div>
</body>

</html>


#page-container {
  position: relative;
  min-height: 100vh;
}

#content-wrap {
  padding-bottom: 2.5rem;    /* Footer height */
}

#footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 2.5rem;            /* Footer height */
}

What I did

Html

    <div>
      <div class="register">
         /* your content*/    
      </div>
      <div class="footer" />
  <div/>

CSS

.register {
          min-height : calc(100vh - 10rem);
  }

.footer {
         height: 10rem;
 }

Don't need to use position fixed and absolute. Just write the html in proper way.

It's actually very simple. This solution doesn't require to know footer height.

<body>
  <div class="app">
    Website
  </div>
  <div class="footer">
    Footer
  </div>
</body>
.app {
  min-height: 100vh;
}

Some solutions didn't work for me but the best option I found was the example below when I decided to use the flex option.

html, body{
    height: 100%;   
}

body{
    display: flex;
    flex-direction: column;
}

.main-contents{ 
    flex: 1 0 auto;
    min-height: 100%;
    margin-bottom: -77px;
  background-color: #CCC;
}

.footer{
    height:  77px;
    min-height: 77px;
    width: 100%;
    bottom: 0;
    left: 0;
    background: #000000;
    flex-shrink: 0;
    flex-direction: row;
    position: relative;
    
    
}

.footer-text{
  color: #FFF;
}

@media screen and (max-width: 767px){
    #content{
        padding-bottom: 0;
    }
    .footer{
        position: relative;
        /*position: absolute;*/
        height: 77px;
        width: 100%;
        bottom: 0;
        left: 0;
    }

}
<html>
  <body>
    <div class="main-contents" >
      this is the main content
    </div>
  </body>

  <footer class="footer">
    <p class="footer-text">This is the sticky footer</p>
  </footer>

</html>

For the fixed height footers, you can also use css variables to do it.

/* Globals */

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body {
  font-family: Arial;
}

main {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: calc(100vh - var(--navbar-height) - var(--footer-height));
  background-color: #1b1b1b;
  color: cyan;
}


/* Navbar */

:root {
  --navbar-height: 60px;
}

.navbar {
  display: flex;
  justify-content: center;
  align-items: center;
  height: var(--navbar-height);
  color: white;
  background-image: linear-gradient(75deg, yellow, orange);
}


/* Footer */

:root {
  --footer-height: 40px;
}

footer {
  display: flex;
  justify-content: center;
  align-items: center;
  height: var(--footer-height);
  color: white;
  font-weight: 700;
  background-image: linear-gradient(70deg, yellow 0%, orange 25%, teal 25%, cyan 50%, red 50%, magenta 75%, black 75%, grey 100%);
  /* background-image: linear-gradient(70deg, black 0%, cyan 100%); */
}
<body>
  <nav class="navbar">Navbar</nav>
  <main>Main Section</main>
  <footer>&copy; Test 2021 - FOREVER ❤♾</footer>
</body>

<!DOCTYPE html>

<html>
 <head>
   <link rel="stylesheet" type="text/css" href="main.css" />
 </head>

<body>
   <header class='header'></header>
   <div class="body-content">
     <!-- all other page content -->
   </div>
   <footer class="footer"></footer>
</body>

</html>

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

.body-content {
  flex-grow:1   
}
<body>
    <section class="wrapper">
        <!--Some Content-->
    </div>

    <section class="footer"></section>
</body>

.wrapper {
    min-height: 100vh;
}

.footer {
    top: 100vh;
}
Related