Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Footer at bottom of page or content, whichever is lower

Tags:

html

css

footer

I have the following structure:

<body>     <div id="main-wrapper">         <header>         </header>         <nav>         </nav>         <article>         </article>         <footer>         </footer>     </div> </body> 

I dynamically load content in the <article> using javascript. Because of this, the height of the <article> block can change.

I want the <footer> block to be at the bottom of the page when there is a lot of content, or at the bottom of the browser window when only a few lines of content exist.

At the moment I can do one or the other... but not both.

So does anyone know how I can do this - get the <footer> to stick to the bottom of the page/content or the bottom of the screen, depending on which is lower.

like image 374
Will Avatar asked Sep 02 '12 19:09

Will


People also ask

How do I stick footer to the bottom when page content is less?

Quick answer: Add “display:flex; flex-direction:column; min-height:100vh;” to body or appropriate layout body element, then add “flex:1;” to content wrapper element/section. I will explain few ways to keep or stick the footer to the bottom of the page if there is not enough content.

Does the content in the footer appear at the bottom?

By this, if article has only few lines of content, the footer will stick to the bottom of the browser window, otherwise it will go below all the content.

How do you position the footer at the bottom of the page?

Keep the footer at the bottom by using Flexbox 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.

How do I keep the footer at the bottom of the page with dynamic height?

If you wrap the content in a tag and set the margin-bottom value to the same as the footer-height, you would be able to read the text that the footer was originally covering.


2 Answers

Ryan Fait's sticky footer is very nice, however I find its basic structure to be lacking*.


Flexbox Version

If you're fortunate enough that you can use flexbox without needing to support older browsers, sticky footers become trivially easy, and support a dynamically sized footer.

The trick to getting footers to stick to the bottom with flexbox is to have other elements in the same container flex vertically. All it takes is a full-height wrapper element with display: flex and at least one sibling with a flex value greater than 0:

CSS:
html, body {   height: 100%;   margin: 0;   padding: 0; }  #main-wrapper {   display: flex;   flex-direction: column;   min-height: 100%; }  article {   flex: 1; } 

html,  body {    height: 100%;    margin: 0;    padding: 0;  }  #main-wrapper {    display: -webkit-box;    display: -ms-flexbox;    display: flex;    -webkit-box-orient: vertical;    -webkit-box-direction: normal;        -ms-flex-direction: column;            flex-direction: column;    min-height: 100%;  }  article {    -webkit-box-flex: 1;        -ms-flex: 1;            flex: 1;  }  header {    background-color: #F00;  }  nav {    background-color: #FF0;  }  article {    background-color: #0F0;  }  footer {    background-color: #00F;  }
<div id="main-wrapper">     <header>       here be header     </header>     <nav>     </nav>     <article>       here be content     </article>     <footer>       here be footer     </footer>  </div>

If you can't use flexbox, my base structure of choice is:

<div class="page">   <div class="page__inner">     <header class="header">       <div class="header__inner">       </div>     </header>     <nav class="nav">       <div class="nav__inner">       </div>     </nav>     <main class="wrapper">       <div class="wrapper__inner">         <div class="content">           <div class="content__inner">           </div>         </div>         <div class="sidebar">           <div class="sidebar__inner">           </div>         </div>       </div>     </main>     <footer class="footer">       <div class="footer__inner">       </div>     </footer>   </div> </div> 

Which isn't all that far off from:

<div id="main-wrapper">     <header>     </header>     <nav>     </nav>     <article>     </article>     <footer>     </footer> </div> 

The trick to getting the footer to stick is to have the footer anchored to the bottom padding of its containing element. This requires that the height of the footer is static, but I've found that footers are typically of static height.

HTML:
<div id="main-wrapper">     ...     <footer>     </footer> </div> 
CSS:
#main-wrapper {     padding: 0 0 100px;     position: relative; }  footer {     bottom: 0;     height: 100px;     left: 0;     position: absolute;     width: 100%; } 

#main-wrapper {    padding: 0 0 100px;    position: relative;  }    footer {    bottom: 0;    height: 100px;    left: 0;    position: absolute;    width: 100%;  }    header {    background-color: #F00;  }  nav {    background-color: #FF0;  }  article {    background-color: #0F0;  }  footer {    background-color: #00F;  }
<div id="main-wrapper">     <header>       here be header     </header>     <nav>     </nav>     <article>       here be content     </article>     <footer>       here be footer     </footer>  </div>

With the footer anchored to #main-wrapper, you now need #main-wrapper to be at least the height of the page, unless its children are longer. This is done by making #main-wrapper have a min-height of 100%. You also have to remember that its parents, html and body need to be as tall as the page as well.

CSS:
html, body {     height: 100%;     margin: 0;     padding: 0; }  #main-wrapper {     min-height: 100%;     padding: 0 0 100px;     position: relative; }  footer {     bottom: 0;     height: 100px;     left: 0;     position: absolute;     width: 100%; } 

html,  body {    height: 100%;    margin: 0;    padding: 0;  }    #main-wrapper {    min-height: 100%;    padding: 0 0 100px;    position: relative;  }    footer {    bottom: 0;    height: 100px;    left: 0;    position: absolute;    width: 100%;  }    header {    background-color: #F00;  }  nav {    background-color: #FF0;  }  article {    background-color: #0F0;  }  footer {    background-color: #00F;  }
 <div id="main-wrapper">     <header>       here be header     </header>     <nav>     </nav>     <article>       here be content     </article>     <footer>       here be footer     </footer>  </div>

Of course, you should be questioning my judgement, as this code is forcing the footer fall off the bottom of the page, even when there's no content. The last trick is to change the box model used by the #main-wrapper so that the min-height of 100% includes the 100px padding.

CSS:
html, body {     height: 100%;     margin: 0;     padding: 0; }  #main-wrapper {     box-sizing: border-box;     min-height: 100%;     padding: 0 0 100px;     position: relative; }  footer {     bottom: 0;     height: 100px;     left: 0;     position: absolute;     width: 100%; } 

html,  body {    height: 100%;    margin: 0;    padding: 0;  }    #main-wrapper {    box-sizing: border-box;    min-height: 100%;    padding: 0 0 100px;    position: relative;  }    footer {    bottom: 0;    height: 100px;    left: 0;    position: absolute;    width: 100%;  }    header {    background-color: #F00;  }  nav {    background-color: #FF0;  }  article {    background-color: #0F0;  }  footer {    background-color: #00F;  }
 <div id="main-wrapper">     <header>       here be header     </header>     <nav>     </nav>     <article>       here be content     </article>     <footer>       here be footer     </footer>  </div>

And there you have it, a sticky footer with your original HTML structure. Just make sure that the footer's height is equal to #main-wrapper's padding-bottom, and you should be set.


* The reason I find fault with Fait's structure is because it sets the .footer and .header elements on different hierarchical levels while adding an unnecessary .push element.

like image 170
zzzzBov Avatar answered Sep 28 '22 05:09

zzzzBov


Ryan Fait's sticky footer is a simple solution that I have used several times in the past.

Basic HTML:

<div class="wrapper">     <div class="header">         <h1>CSS Sticky Footer</h1>     </div>     <div class="content"></div>     <div class="push"></div> </div> <div class="footer"></div> 

CSS:

* {     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 */ }  /*  Sticky Footer by Ryan Fait http://ryanfait.com/  */ 

Translating this to be similar to what you already have results with something along these lines:

HTML:

<body>     <div class="wrapper">         <header>         </header>         <nav>         </nav>         <article>         </article>         <div class="push"></div>     </div>     <footer>     </footer> </body> 

CSS:

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

Just dont forget to update the negative on the wrapper margin to match the height of your footer and push div. Good luck!

like image 21
Josh Mein Avatar answered Sep 28 '22 04:09

Josh Mein