Looking for office space? Headscape has space free at the Barn again.
Fixed Footers without JavaScript
Posted in Technology on: Thursday, September 4, 2008 by Paul Boag
Ed Merritt (one of our very awfully clever designers at Headscape) has come up with a innovative little CSS technique I have encouraged him to share with you.
A client recently asked me if it was possible to have a page footer which would stick to the bottom of the browser window if the content didn’t fill the window, but behave normally (i.e. be pushed down by the content) when the content was tall enough.
This footer behaviour is not a new idea; I’ve seen it on a few sites over the years, the most well known probably being version 7 of Shaun Inman’s site. Take a look at the ‘Work’ page with JavaScript enabled, then disabled to see the effect in action.
I suspect that this behaviour, which can look great in the right situation, has not been widely adopted because existing solutions have always relied on JavaScript for what should be a simple presentation issue.
The technique described in this article is purely a CSS solution and works in all modern browsers, tested down to IE5.5.
Firstly, here’s a demonstration.
The HTML
<div id="container"> <div id="content"></div> <div id="footer"></div> </div>
The CSS
*, body {margin: 0; padding: 0;} #container {display: block; position: absolute; min-height: 100%;} #content {display: block; margin-bottom: 3em;} #footer {position: absolute; display: block; bottom: 0; height: 3em }
IE6 Stylesheet
body, #container {height: 100%;}
this should be referenced using a conditional comment:
<!--[if lt IE 7]> <link href="css/ie6.css" rel="stylesheet" type="text/css" media="screen" /> <![endif]-->
How it works
As you can see, the mark-up and styling are pretty simple. Here’s a quick run-through of what’s going on…
- #container is set to be at least as tall as the browser window using min-height and although IE6 doesn’t understand this, it treats height in exactly the same way. #container must be positioned absolutely, or this will not work.
- #footer is positioned absolutely at the bottom of #container
- #content is given a bottom margin equal to the height of #footer to prevent the two ever overlapping.
Known Issues
The simplicity of this technique makes it fairly reliable and the only real issues to consider are for IE6 and below. For these browsers you’ll need to specify any additional containers as also having a height of 100%.
For example, if your mark-up was:
<div id="extraContainer"> <div id="container"> <div id="content"></div> <div id="footer"></div> </div> </div>
In your IE specific CSS you’d need to specify:
body, #extraContainer, #container {height: 100%;}
Conclusion
This is a nice and easy solution to those unsightly gaps below your footers and while it won’t be appropriate for every site, it might come in handy from time to time. Please let me know if you find any problems with it.
Additional comments powered by BackType




29 Comments
Comments are for the discussion of this post. If you have other questions / comments then post them to the forum or send me an email
I used a very similar technique on a previous project, you need to add a bit more CSS to take care of the form if your using ASP .net. More here:
http://fordie.co.uk/index.php/2007/10/25/how-to-create-a-sticky-footer-in-aspnet-pages/
Nice idea and well executed.
Just a thought – and might be being a complete numpty here – but does the display: block; property need to be defined in the main css file?
Cole
Another way to do it:
http://www.themaninblue.com/writing/perspective/2005/08/29/
I’ve used this method numerous times, but it always seems to take a couple hours to get it to work properly. Margin collapsing can throw it off and add a vertical scroll bar if you’re not careful though.
Thanks for sharing this method… I’ll try it next time.
@ Mark Ford
I’ve never had a problem with ASP.NET wrapping everything in a form. I thought it only wraps the stuff you place inside it. Some controls won’t work if not inside it.
My main gripe is Viewstate. If you havn’t already checked out ASP.NET MVC, it’s worth a look. I’m waiting for it to get out of beta:
http://www.asp.net/mvc/
Also using “xhtmlConformance mode=”Strict”" is a nice little trick (gets rid of name attributes :)
Useful technique, however, seems the absolute positioning overrides my margin: 0 auto; method of centering content. Now my site is flush left. Any solutions for maintaining a centered layout?
@Jim, this should work:
#container {display: block; position: absolute; min-height: 100%; width: 100%;}
#content {display: block; width: 60%; margin: 0 auto 3em auto; }
@Marc Wickens I guess you’ve been lucky!
The last two projects I’ve worked on the .net devs have insisted on wrapping everything inside the body tag in the .net form.
fotunately we’re now moving to the .net MVC framework, which makes me a happy front end dev.
oh & I agree about the xhtmlConformance mode=”Strict” thing: http://fordie.co.uk/index.php/2007/10/25/quick-tip-for-using-xhtml-strict-with-aspnet/
Not sure, but it looks like it isn’t working properly in IE6. Anyway, nice work!
This is the method I’ve been using for a while; it looks to be pretty much the same as the example(s) above:
http://www.xs4all.nl/~peterned/examples/csslayout1.html
Thanks for sharing, Paul. The downside of these demos are that in the real world things look different. Why do someone choose a footer to be fixed at the bottom: to have it visible always. In your demo, if I put more lines of text in the page, the footer disappears.
I mostly make use of:
expression(document.body.offsetHeight – n + “px”);
Give a fixed header and footer, and a scrollable midsection. Like frames used to be. It all scales with the browser window.
I can’t post the site I use it in, but I can mail it to you.
Did you not bother to test in Opera? It doesn’t work if you resize the window.
Someone said it doesn’t work properly in IE6. The example doesn’t work AT ALL in IE 6! What a waste of time! Come on!
@John and @Terrance… There was a tiny error in the example code which was breaking the demo in IE6 and Opera. I have fixed it now and so it should work correctly. Apologises for that.
As soon as I saw your matching padding I knew I saw it somewhere. Yea, http://ryanfait.com/sticky-footer/ back in April, that was it!
boag as in bogus!
It never ceases to amaze me how no matter how hard one works on something, trolls will pop up and make sure everyone knows they have no creativity of their own whatsoever.
BillyG. Get a life. And no, before you waste time searching Google, you can not actually download a real life, you actually have to go and live it.
…
Anyway, Great job Paul. This was insightful and I may make use of it in my new portfolio. I was planning on just a fixed tag with fallback but this is much cleaner. Thank you for calling attention to, and documenting this method!
Billy G, just in passing. While there is a similarity in the code, the version you linked to uses height auto: !important, and I think this one is a little better. But yes it is on the same track. But not the same IMO.
Just at a glance.
Lance, ripping off someone else’s solution is worse than pointing out that someone has done just that. Consider whether you’re raging against the right person here.
Nothing new here. Matthew Taylor posted this very technique back in Nov. 2007.
http://matthewjamestaylor.com/blog/keeping-footers-at-the-bottom-of-the-page
I liked the CSS section. I would listen to an entire show on CSS but I think a brief section is more realistic. There is a lot to CSS and I like to hear about some of its intricacies.
Hey guys, this is what I’ve been using to get footers to stick to the bottom of a page. Got the original from the xs4all.nl site mentioned in an earlier comment.
The only difference with the version presented here is the use of padding instead of margin. Not even sure why, must have been a background image issue.
Just what I’ve been looking for, cheers guys!
This method is not Ryan Fait’s Stickyfooter technique as suggested above because it doesn’t require the extra empty “push” div.
It’s a shame that people have to be so quick to criticize something when the good people at Boagworld are spending their time to be helpful and informative. If you read the top of the post after Paul’s bit it clearly says “This footer behaviour is not a new idea; I’ve seen it on a few sites over the years”.
Food for thought: N,o one gets any brownie points here for being uber critical, and being so doesn’t make you look any more intelligent.
Are you *sure* it works with an extra container? I had to use an extra container for a background image – IE 7 does not enlarge backgrounds on BODY when zooming. I could not get it to work at all. Didn’t even get to trying in IE 6 as all other browsers failed to work. Hmm.
I had a similar dilemma recently and found this page which worked a treat too.
http://www.dave-woods.co.uk/index.php/css-fixed-footer/
This was just what I needed!
Haters seem so ignorant. Keep up the good work.
The example still does not work for me in IE6 or Opera 9.1. Seems that the conditional comment doesn’t work. Using the IE Developer Toolbar I don’t see 100% on the body or wrapper. When I add 100% height to them through the IE Dev Toolbar, it works. I changed the CC to gte IE 5.5 and it works. May have something to do with the fact I was running multiple IEs hack? It actually works fine when I remove the CC altogether. Notice body and #wrapper selectors appear twice.
Use this:
*, body {margin: 0; padding: 0; position: static;}
#wrapper {display: block; position: absolute; min-height: 100%; background: #eee;}
#content {display: block; background: #ddd; margin-bottom: 3.3em; padding: 1em; width: 600px; border-bottom: 1px solid #bebebe;}
#footer {position: absolute; display: block; bottom: 0; display: block; background: #ccc; padding: 1em; border-top: 1px solid #c6c6c6; width: 600px;}
h1, p {margin-bottom: 20px;}
body, #wrapper {height:100%;}
Demo at…
http://rci.rutgers.edu/~tako/footerBottomStick.html
Nice tutorial. I think this is the best “fixed footer” example i’ve seen so far!
If you want to, you could strip it down a bit by letting the body element act as a content wrapper. In other words, you could get rid of the container div. The example below also deals with centering the content:
*, body {margin: 0; padding: 0;}
body {position:absolute; min-height:100%; width:800px; margin-bottom:3em; left:50%; margin-left:-400px;}
#content {margin-bottom:3em;}
#footer {position:absolute; bottom:0; height:3em;}
Thanks Paul! I had searched around for a bit to find one that does exactly what your example does, but to no avail. This works exactly as expected… thank you!
Hey cool, thanks for this tip.
You really helped me!!