Sticky Footer

Cristian in CSS, Javascript

January 23, 2009

During the years I’ve been through so many solutions to achieve a sticky footer solution, from the one explained at Exploring Footers (A List Apart) to different variations that at Gimmicklab we have re-using and re-thinking, some based on pure CSS and some taking advantage of Javascript.

Yesterday I was taking a look at CSS Sticky Footer, a pure CSS technique that provides this functionality with full crossbrowser compatibility.

We have been using a similar method in the past with great results, but the thing that I’ve been always complaining is that it made me change our mark up structure.

Since we work with a XHTML and CSS styleguide for our every project that establish the following general mark up among other rules:

<div id="container">
	<div id="header"><div>
	<div id="main"><div>
	<div id="footer"><div>
<div>

So changing the structure wasn’t fitting all our necessities, considering that to make it run only with CSS we should close #container element right after the# main , leaving the #footer outside the general structure.

<div id="container">
	<div id="header"><div>
	<div id="main"><div>
<div>
<div id="footer"><div>

Although this is a clever techniqe and due to the high volume of projects that we are working, our necessity of a solid structure across several projects it’s actually stronger than any design necessity, so we finally developed a script to achieve the same effect with our actual general mark up. And it’s reusable for every different structure.

The XHTML mark up is the following:

<div id="container">
	<div id="header"><div>
	<div id="main"><div>
	<div id="footer"><div>
<div>

And the CSS, you should apply after any kind of CSS reset. I suggest Eric Meyer’s approach.

body, html, #container {
	height: 100%;
}
#main {
	height: auto;
}

You can fix a height for the header and the footer if you like, even in the container if you want to try different layout structures.

And now some Javascript code.

function matchHeight() {
	var finalHeight = document.getElementById('container').offsetHeight - document.getElementById('header').offsetHeight - document.getElementById('footer').offsetHeight;
	var mainElement = document.getElementById('main');
	mainElement.style.height = finalHeight + 'px';
}
window.onload = matchHeight;
window.onresize = matchHeight;

As you can see you have to set body, html and #container to 100%, and give to #main an automatic witdh.

The javascript determines the exact height of the main element pushing the footer element until the end of the page.

The main height size is the result to calculate the container height (100% of the viewport) minus the header and footer height.

And here it is a Jquery version of the javascript code:

$(function(){
	matchHeight();
	function matchHeight() {
		var mainHeight = $("#container").outerHeight() - $("#header").outerHeight() - $("#footer").outerHeight();
		$('#main').height(mainHeight);
	}
	$(window).resize(matchHeight);
});

We tested the technique in diferent browsers and OS: Firefox (Win/Mac/Linux), Safari (Win/Mac/Iphone), IE6, IE7, IE8 (Windows), Opera (Mac).

The complete code and example page with Javascript and JQuery.

Comments(4)

  1. 1.
    Daniel Hüsch January 23, 2009 at 9:08 pm

    That looks nice and the list of tested configurations is impressive.
    I still have two general JS tweaks to offer that reduce the amount of code which is, in my opinion always a good thing, as long as it doesn’t degrade readability and by that maintainability.

    My first hint is for JS in general. In JS there are two kinds of function references. The first one is an anonymous function, exactly what you used above. The second one is the name of any already defined function, which is especially helpful in case you want to register an event handler that just calls another parameterless function. Instead of writing
    window.onresize = function() {
    matchHeight();
    }
    you could just write window.onresize = matchHeight;This works with jQuery as well.
    $(window).resize(function(){
    matchHeight();
    });
    can be reduced to $(window).resize(matchHeight);
    My second hint is jQuery related and makes use of my first hint. Instead of saying $(document).ready(some_function); you can always pass that function reference directly to the $ function, like $(some_function);

  2. 2.
    Cristian January 24, 2009 at 2:19 am

    Hi Daniel!

    Thanks for your tips, I just added them to the code. Now that I’m getting introduced to Javascript and Jquery it’s nice to see some shorthand variations and best practices.

  3. 3.
    Chris Poteet April 1, 2009 at 7:08 pm

    You might also want to check to make sure the content div is less than the windows height to apply the effect. Here’s my modification.

    function matchHeight() {

    var winHeight = $(window).height();
    var wrapHeight = $(“#wrapper”).height();

    var mainHeight = $(window).height() – $(“#header”).height() – $(“#footer”).height();
    var mainHeight2 = mainHeight + 91;

    if (wrapHeight < winHeight) {
    $(‘#wrapper’).height(mainHeight2);

    }
    }

    I based it off of this article by ALA which checks the condition.

  4. 4.
    Cristian April 2, 2009 at 1:52 pm

    Nice! It makes more sense now. I will add it to the example. Thanxs for sharing!

Insert Comment