views:

311

answers:

2

I've been using this snippet of jQuery to get a sticky footer:

if($(document.body).height() < $(window).height()){
        $("#footer").css({
            position: "absolute",
            top:  ( $(window).scrollTop() + $(window).height()
                  - $("#footer").height() ) + "px",
            width: "100%"
       });
}
$(window).scroll(positionFooter).resize(positionFooter);

However, that breaks when I've got expandable/collapsible divs lying around where the original content was less high than the window, since it is then stuck to the bottom of the window, rather than the bottom of the document.

Is there a way of fixing this, or a better way of doing it?

Please bear in mind that I don't have much control over the HTML, since I need to do this in Django's admin interface, which doesn't allow much injection of HTML in the places you might want to to accomplish this sort of thing (i.e. this answer and this answer don't work for me).

+5  A: 

So you don't want to position the footer absolutely anymore when the document height is higher than the window height? Then add an else statement which does exactly that:

if($(document.body).height() < $(window).height()){
    $('#footer').css({
        position: 'absolute',
        top:  ( $(window).scrollTop() + $(window).height()
              - $("#footer").height() ) + "px",
        width: "100%"
    });
} else {
    $('#footer').css({
        position: 'static'
    });
}   

Here's a live demo. Note that I added click event to $(window) because the resize doesn't get triggered in FF when you expand/collapse a div.

BalusC
+1 just what I thought. And don't forget to call `positionFooter()` when you toggle an element.
galambalazs
@galam: That's taken care by adding `click` to `$(window)` event listener. This is by the way not needed for IE.
BalusC
@BalusC it works in most cases, but if there is an *ancestor* of the *toggler* element which stops *event bubbling*, then it won't get to `window` http://jsbin.com/ejabe
galambalazs
@gala: that's pretty an edge case.
BalusC
@BalusC yes and no. :) Stopping even delegation can happen anywhere, intentionally or not. A simple `return false` is enough to break the code. Unfortunately I saw use cases where one's habit was to end every event handler like this (whether its appropriate or not).
galambalazs
holy crap jsfiddle.net looks awesome.
Tim Coker
+1  A: 

I used this approach to sticky footers and dynamic content (but my application was slightly more complicated to integrate than the examples) and it works: http://www.cssstickyfooter.com/

pablorc