Position footer at bottom of page having fixed header
Asked Answered
H

6

21

I want to position the footer at the bottom of the page which having a fixed header also...

  • Not with position: fixed - I don't want it to remain on the screen, it should just be at the end of the page and behave normally when scrolling.

  • Not at the bottom of the visible screen - At the bottom of the page, i.e; after all other content.


Here's a diagram to explain better:

Footer problem


Here's the code:

  • I have prepared a demo: JSFiddle
  • Or see below
<div id="header">Header</div>
<div id="content">
    <p>Some content...</p>    
</div>
<div id="footer">Footer</div>
body{
    /* Just to enable scrolling in JSFiddle */
    height: 1000px;
}

#header{
    width: 100%;
    height: 100px;
    position: fixed;
    top: 0px;
    z-index: 1;
}

#content{
    width: 100%;
    position: absolute;
    top: 100px; /*Height of header*/
    z-index: 0;
}

#footer{
    width: 100%;
    height: 100px;
    position: absolute;
    bottom: 0px;
}

/*For demo only*/
#header, #footer{
    border: 3px dashed #333333;
    background: #FFFFFF;
}

#content{
    background: #CCCCCC;
    height: 200px;
}
Hemihedral answered 27/8, 2013 at 15:9 Comment(8)
I seem to have a problem with the formatting of the code. If anyone can edit I'd appreciate.Hemihedral
Are you using IE? Formatting does be messed up when I view it in IE!Rangy
Does content need to has absolute position?Trichiasis
Why not just using some relative positions for your content and your footer? i mean you use a margin-top : 100px; for content and you just put the footer after it.Tiv
@HashemQolami, I think so. Because the header has fixed position, so it makes sure that the content is visible.Hemihedral
Ok I don't get what's wrong. In your demo the footer is positioned at the bottom of all your content like you wantCongeneric
Then remove position absolute on the content, and instead give it a top margin the same size as the header heightPennebaker
@Hemihedral I've just updated my answer with two alternative solution, please let me know how it works.Trichiasis
T
36

As you have mentioned, position: fixed would position the footer with the respect to the viewport rather than the page itself. Therefore, we have to keep the element in normal flow and somehow position it to the bottom of the page.

There are couple of approaches to achieve that, which have been discussed in the wild during the time.
For instance:

Sticky Footer

In this answer I'd go with Ryan Fait's method since it is simple and easy to understand and also it meets your needs (Situations where both header and footer have fixed heights).

Considering the structure below:

<div id="content"> <!-- content goes here. It may (not) include the header --> </div>
<div id="footer">Footer</div>

The following steps are needed:

  1. Setting height of the <html> and <body> elements to 100% which is required for the next step1.

  2. The most important thing we need to do is to make sure that the #content is high enough to push the #footer down the page. Hence we give the #content a min-height of 100%.

  3. So far, the #content has taken 100% of height of the viewport, thus we should pull the footer up to position it at the bottom of the page. In order to do that we could give the #content a negative margin-bottom equivalent to the footer's height. Also to make sure that the footer appears on top of the content, we should position the footer relatively. Demo Here.

  4. As can be seen, when the #content grows by its contents, some of the contents go behind the footer. We could avoid that either by appending a spacer element at the end of #content or use the combination of padding-bottom and box-sizing: border-box2 which is supposed to be supported on IE8 as well.

4.1 Adding a spacer

Example Here

<div id="content">
    <!-- content goes here -->
    <div class="spacer"></div>
</div>
<div id="footer">Footer</div>
.spacer, #footer { height: 100px; }

4.2 Combination of padding-bottom and box-sizing

Updated Example

#content {
    min-height: 100%;
    margin-bottom: -100px; /* Equivalent to footer's height */
    padding-bottom: 100px; /* Equivalent to footer's height */

    box-sizing: border-box;
}

(Note that vendor prefixes omitted due to brevity)


Adding the Header

  1. If the header should remain in normal flow, you could simply add it to the #content as follows:
    (Example Here)

    <div id="content">
        <div id="header">Header</div>
        ...
    
  2. But if it should be positioned absolutely3, we need to push the contents of #content element down in order to prevent overlapping.

Therefore, again, we could either add a spacer at the beginning of #content (Example Here):

<div id="header">Header</div>
<div id="content">
    <div class="header-spacer"></div> 
    <!-- content goes here -->
    <div class="footer-spacer"></div> 
</div>
<div id="footer">Footer</div>

Or use the combination of padding-top and box-sizing as follows:

<div id="header">Header</div>
<div id="content"> <!-- content goes here. --> </div>
<div id="footer">Footer</div>
#content {
    min-height: 100%;
    margin-bottom: -100px; /* Equivalent to footer's height */

    padding-top   : 50px;  /* Equivalent to header's height */
    padding-bottom: 100px; /* Equivalent to footer's height */

    box-sizing: border-box;
}

Updated Example (Note that vendor prefixes omitted due to brevity)

At last but not least!

Nowadays, All major modern web browsers support box-sizing: border-box declaration (including IE8). However if you're looking for the traditional way which has a wider browser support, stick with using spacer elements.


1. This is needed to make min-height: 100% to work on the #content element (because a percentage value is relative to the height of the box's containing block which is established by the <body>). Also <html> should have an explicit height to make height: 100% to work on <body>.

2. box-sizing: border-box makes UAs calculate the width/height of the box including padding and borders.

3. According to spec, absolutely positioned elements are elements having a position of absolute or fixed.

Trichiasis answered 27/8, 2013 at 15:24 Comment(3)
Thanks, this is working great for me. I'm using JSFiddle #1, but I removed box sizing, it seems to be working on all browsers (including IE7) - jsfiddle.net/33vQy/2Hemihedral
@Hemihedral You're welcome :) In fact, in this case, box-sizing: border-box; prevents page from scrolling when it is not needed.Trichiasis
Outstanding explanationUralaltaic
A
3

You almost got it. What you need is a container.

Here is my revised bit: JSFiddle Update

Add a container div:

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

Then make the position relative, and the height 100%:

#container {
    height: 100%;
    position: relative;
}

And make sure the position is absolute for the footer.

Arbela answered 27/8, 2013 at 15:20 Comment(1)
The problem is that if I remove the body height property, then it stops working.Hemihedral
C
3

Or for those who found this post by googling and want an even shorter answer, without wrappers (because you don't need them):

html { height: 100%; }
body { min-height: 100%; position: relative; padding-bottom: 3em; }
.footer { height: 3em; position: absolute; bottom: 0; }

done, the page is now at least 100% screen height, and the footer is at the bottom of the page, not the bottom of "the screen". If the page is longer than the screen, it'll still be at the bottom, and we did it without artificial "wrapper elements" or the likes: the body element is already the wrapper we need =)

The only caveat is that the body margin needs to be the same as the footer height, but then as negative value, since the "bottom: 0" rule will make the footer start at the bottom instead of baseline-anchored. Then again, as CSS, .less or .styl, this is trivially ensured.

Catadromous answered 28/12, 2013 at 19:58 Comment(1)
Thanks, but you missed the punctuation ":" after the word "bottom". After correcting that the code worked ok!Brose
O
0

To do it simple:

#header {
    position: fixed;
    width:100%;
    height:100px;
    top:0px;
    z-index:2;
}
#content, #footer {
    position: relative; /* or leave it static as by default */
    z-index:1;
}
body,div {
    margin:0; padding:0; /* http://jsfiddle.net/css/normalize.css */
}
#content {
    margin-top: 100px; /* the same value as header's height */
}

jsfiddle

Overfly answered 27/8, 2013 at 16:50 Comment(0)
D
0
But if you want the footer to take full size of the screen while #wrapper is 1000px and centered you would do:


<body>
<div id="wrapper">
<div id="wrapper-inner">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
</div>
</body>

html,
body {
margin:0;
padding:0;
height:100%;
}
#wrapper {
min-height:100%;
position:relative;
}
#wrapper-inner {
margin: 0 auto;
width: 1000px;
}
#content {
padding:10px;
padding-bottom:80px; /* Height of the footer element */
}
#footer {
width:100%;
height:80px;
position:absolute;
bottom:0;
left:0;
}
Dishwater answered 22/1, 2015 at 6:8 Comment(0)
H
0

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 my footer can have different heights on different sections of the web app. And 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

Holofernes answered 14/12, 2018 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.