Grow your CSS skills. Land your dream job.

Last updated on:

jQuery Sticky Footer

In general the CSS Sticky Footer is the best way to go, as it works perfectly smoothly and doesn't require JavaScript. If the markup required simply isn't possible, this jQuery JavaScript might be an option.

HTML

Just make sure the #footer is the last visible thing on your page.

<div id="footer">
    Sticky Footer
</div>

CSS

Giving it a set height is the most fool-proof.

#footer { height: 100px; }

jQuery

When the window loads, and when it is scrolled or resized, it is tested whether the pages content is shorter than the window's height. If it is, that means there is white space underneath the content before the end of the window, so the footer should be repositioned to the bottom of the window. If not, the footer can retain it's normal static positioning.

// Window load event used just in case window height is dependant upon images
$(window).bind("load", function() { 
       
       var footerHeight = 0,
           footerTop = 0,
           $footer = $("#footer");
           
       positionFooter();
       
       function positionFooter() {
       
                footerHeight = $footer.height();
                footerTop = ($(window).scrollTop()+$(window).height()-footerHeight)+"px";
       
               if ( ($(document.body).height()+footerHeight) < $(window).height()) {
                   $footer.css({
                        position: "absolute"
                   }).animate({
                        top: footerTop
                   })
               } else {
                   $footer.css({
                        position: "static"
                   })
               }
               
       }

       $(window)
               .scroll(positionFooter)
               .resize(positionFooter)
               
});

Demo

View Demo

Comments

  1. Seems to have a few kinks… appears to queue animations if you keep resizing and dragging the window size larger and smaller?

    • you could either just add a .stop(); before the animation. Or, don’t use .animate at all, just set the top value with the .css function. Just a little jerky that way.

    • BEata
      Permalink to comment#

      I am using your demo files that already has the stop() in it and the animation is till happening.
      How can I stop it at all and just have the footer stay at the bottom of the page?

      $footer.css({
      position: “absolute”
      }).stop().animate({
      top: footerTop
      })
      } else {
      $footer.css({
      position: “static”
      })
      }

  2. Permalink to comment#

    sorry, but it is not very smooth… what’s about:
    { position: fixed; bottom: 0; width: 100%; }

    • That is completely against the whole point of this. This STOPS before the bottom of the content, so it doesn’t overlap any content. Fixing it to the bottom will happily lay over the top of content.

    • Permalink to comment#

      That is completely against the whole point of this. This STOPS before the bottom of the content, so it doesn’t overlap any content. Fixing it to the bottom will happily lay over the top of content.

  3. EVula
    Permalink to comment#

    Mac 10.5.8, Safari 4.0.3… this is incredibly buggy. Resizing the window makes the footer shift (a good thing), but it doesn’t sit flush with the bottom of the window, instead having a big white border show thru. Eww.

    • Seems to be running fine for me with the same exact specs. I just added the .stop() before the animate, which might help. I think Safari was just firing a shit-load of resize events and you computer was probably having trouble to keep up.

    • Seems to be working fine for me.

      OS X 10.6.2 using Chrome 4.0.2, Safari 4.0.4 and FF 3.5.5; keep up the good work.

      It did get a little jumpy but it seems to be more my computer than the code itself.

    • Drift
      Permalink to comment#

      Why so rude? “Eew” is such an awful word to stay. Why not use “Thank you” instead? I mean you couldn’t even produce a javascript code yourself.

      P.S to Mr. Chris:
      Sorry for the rant. Just really pissed off.

  4. Kris
    Permalink to comment#

    Works great and looks great for me on Safari, FF, and Chrome on Snow Leopard.

    Chris, you do good stuff. Keep it up!

  5. Permalink to comment#

    you could achieve the same result entirely through CSS, utilizing 100% heights properly along with absolute positioning… the resulting CSS would actually be more “liquid” when resizing a window, and thus not have the buggy effect of the footer jumping around after the window has been resized. the important thing to pay attention to, is to get the footer to NOT overlap your content, but rather force a scroll when it hits the bottom of that container (which this demo succeeds at)…. example of pure CSS version: http://oribe.com/

    • Vikas
      Permalink to comment#

      Hi this is cool….how did u do this plz give me code for that..thnx

  6. Permalink to comment#

    I usually just stick to CSS when I’m doing a “sticky footer” but this is a cool example, thanks!

  7. Cool example. I like to use this pure CSSsticky footer. Pretty similar to your example but with an empty push div.

  8. Permalink to comment#

    Buenisimo Chris!
    Era justo lo que estaba buscando.
    Mil gracias desde Argentina.
    Mauricio

    Awesome Chris!
    It’s just what I was looking for.
    Thanks a lot from Argentina.
    Mauricio

  9. Ant

    This method has some bugs when using zoom, but it’s good when too lazy to make css trick.

    And advantage of that method is that it works on footer without defined height (some sites have long lists in footer and you cannot use height for it).

    Note that you will have to use width:100% for footer, because position:absolute shrinks width to content. And you may also have to use footer wrapper, if you want to center it.

  10. Stuart

    I love it footers have always gave me issues
    it’s nice thanks.

  11. Fantastic, thank you it is very nice

  12. This is excellent thanks so much. Is there away to make it start from the bottom rather than slide down from the top when the script loads?

  13. Thanks i like trick, its really work

  14. Thanks for sharing.
    his will help in my project.

  15. Luco
    Permalink to comment#

    if you don’t want no namby-pamby animation, add ” ,-1 ” like so:

    BEFORE:

    .animate({
    top: footerTop
    })

    AFTER:

    .animate({
    top: footerTop
    },-1)

    and presto.

  16. Gerd Moors
    Permalink to comment#

    This demo works nice on Mac OS X Lion with Safari, Firefox and Chrome.

    But I’ve the following question:

    I want to display an image in the footer and that image must be center in the middle of that footer.
    I still keep the image seeing on the left of the page…

    Can someone tell me how that can be done?

  17. Permalink to comment#

    oh what a nice solution!
    thanks for the tip!
    +1

  18. W.ill
    Permalink to comment#

    Adding a -10px margin-top to the footer straightened out most of my issues. Setting an absolute width on the footer as well. Takes some toying but works great. Thanks again Chris!

  19. Matthew
    Permalink to comment#

    Wow, I love the new theme on your website. Wish I could plagiarize it, lol, but of course I won’t that would be very unprofessional. I’m still waiting for my moment of inspiration to strike though. Unfortunately I’m just not this talented with graphic arts :(

  20. Permalink to comment#

    Hello.. Maybe I didn’t understand the article, but I was wondering if you could help me make my page work right in Safari. I added {clear:both;} to my CSS to make sure the footer didn’t overlap in Firefox, but Safari is just a complete mess and I’m not sure how to correct it. An example of the content overlaying the footer issue can be found here: (use safari)

    http://www.lifeafterhealth.net/recovery/healthy-things-to-do-each-day/

    I guess I’m trying to “unstick” the footer..? Any ideas :(

  21. Permalink to comment#

    Thx for the post. Very usefull article! Will gonna change smth in my site.

  22. Permalink to comment#

    queue: false might also do the trick :)

  23. Chris
    Permalink to comment#

    Doesn’t work on Firefox 3.6.17 on Windows XP (even the demo page on your website). Also, on IE7 the window keeps sliding down slowly then pops back up then slides back down.

    Just an FYI to anyone wondering about old-browser support for this code. Not a complaint, in fact I think it’s a great piece of code and will probably use it anyway since those are quite old now.

  24. Ok, here is a little modification to the above code. This prevents it from snapping onto the static position, just incase that’s what you were looking for.

    
    $(window).bind("load", function() { 
    
    	var footerHeight = 0,
           footerTop = 0,
    	$footer = $("#footer-container");
    	
    	// Run Once the page is loaded
    	positionFooter();
    
    	// This function keeps the footer at the bottom of the page
    	// without overlaping it's top elements.
    	function positionFooter() {
    	
    		footerHeight = $footer.height();
    		footerTop = ($(window).scrollTop()+$(window).height()-footerHeight)+"px";
    		documentHeight = $(document.body).height();
    		
    		// If footer absolute account for it's height
    		if($footer.css("position") == "absolute"){
    			documentHeight += footerHeight;
    		}
    		
    		if ( documentHeight < $(window).height()) {
    		   $footer.css({
    				position: "absolute",
    				top: footerTop
    		   })
    		} else {
    		   $footer.css({
    				position: "static"
    		   })
    		}
    	
    	}
    	
    	$(window)
    		.scroll(positionFooter)
    		.resize(positionFooter)
    
    });
    
  25. Hi, Can you start using fixed positioning dynamically please? You have a nice following and all but you are doing yourself a disservice by using this old animation technique. Its distracting to the website to have it animate on resize. Try messing with fixed positioning just a bit and doing that in your JS rather than using absolute positioning. It doesn’t jerk. No need for animations. Just try it before you knock it.

    You can see some examples here -> PolaraGolf.com on the checkout page or Klim.com on any of the side floating deals which I did.

    Please let me know when you’re done and I’ll use your plugin. Thanks.

  26. Am I missing something? That code seems more complicated than it needs to be. I made a sticky footer with very few lines of code. Seems to be working perfectly.


    // When document is ready...
    $(document).ready(function() {

    // Introduce short variables
    $box = $('#footer');

    // Call method at page load
    sticky($box);

    // Call function every time window is resized
    $(window).resize(function() {
    sticky($box);
    });

    /*
    * This method is in charge of 'sticking'
    * a DIV to the bottom of the window at all times.
    */
    function sticky($b) {

    // Introduce short variables
    $bHeight = $b.height();
    $wHeight = $(window).height();

    // Manipulate the DIV's style
    $b.css('position', 'fixed');
    $b.css('top', $wHeight - $bHeight);
    }
    });

  27. Chris, as a simple suggestion, I think you might hook into both DOMReady and load events, so that sticky footer would immediately attach to the bottom of the viewport, and if after loading images, it needs to get to its original static positioning, it would.

  28. This fits best for me:

    
    $(window).bind("load", function() { 
                 var footerHeight = 0,
               $footer = $("#footer");
               
           positionFooter();
           
           function positionFooter() {
           
                    footerHeight = $footer.height();
           
                   if ( ($(document.body).height()+(footerHeight)) < $(window).height()) {
                       //must stick to bottom
                       $footer.css({
                            position: "fixed",
                            bottom: 0,
                            left:0,
                            right:0
                       })
                   } else {
                       $footer.attr("style", "");
                   }
                   
           }
    
           $(window).resize(positionFooter);
    });
    
    
  29. I was able to solve this by adding an extra div at end of the footer div. Let say we call that div

    div id=”stickyfooter”>  

    and in css use the following

    #stickyfooter{
    background-color: black;
    background-repeat: repeat;
    bottom: 0;
    height: 100%;
    pointer-events: none;
    position: absolute;
    width: 100%;
    z-index: -1;
    }

    Now the background-color for my case was black. It should possibly change for your case and can possibly work in most cases

  30. Permalink to comment#

    Hey thanks Chris and everyone here.

    Maybe i’m missing something but dont we want to stick the footer to the bottom just if body height is less than window height? So lose the footerHeight its redundant..

    $(window).bind("load", function() {
    
      var $footer = $("#footer");
    
       positionFooter();
    
       function positionFooter() {
    
              if ( $(document.body).height() < $(window).height() ) {
                   //must stick to bottom
                   $footer.css({
                        position: "fixed",
                        bottom: 0,
                        left:0,
                        right:0
                   })
               } else {
                   $footer.attr("style", "");
               }
    
       }
    
       $(window).resize(positionFooter);
    });
    
  31. Permalink to comment#

    Hi! found another way of doing it before I saw this post =)

        <script>
            var div = $("#wrap").height();
            var doc = $(window).height();
    
            if (div < doc ) {
                $("#colophon").addClass('stickyfooter'); ; 
            } 
    
            $(window).resize(function() {
                var div = $("#wrap").height();
                var doc = $(window).height();
    
                if (div < doc ) {
                    $("#colophon").addClass('stickyfooter'); 
                } 
            });
            $(window).resize(function() {
                var div = $("#wrap").height();
                var doc = $(window).height();
    
                if (div+311 > doc ) {
                    $("#colophon").removeClass('stickyfooter'); 
                } 
            });
        </script>
    

    CSS:

    .stickyfooter {
    position:absolute;
    bottom:0px;
    }

    /otherwise it’s just a normal wordpress footer

    The 311 is the height of the footer…

    Although, I think Waynoss way is a bit cleaner…

  32. Nice post man. I’m working on a project that was very useful. thank you!

  33. Nuno
    Permalink to comment#

    Thank you very much Chris Coyier and Øyvind Hauge, both combinations are fine to use with or without animations, and thanks all the others also for sharing thoughts.

  34. Works great man thankyou.

  35. Very helpful. Cheers !

  36. Ardais
    Permalink to comment#

    This is pretty frustrating, this isn’t working at all. It isn’t even throwing any errors on Chrome of Firefox. All you should need is the default jQuery libraries right?

    Mine does absolutely nothing and I cannot figure out for the life of me why…

    • Ardais
      Permalink to comment#

      So for some reason this doesn’t work with an unordered list…

  37. Slight refinement to slide the footer from it’s current position down to the bottom. As originally written, setting position: absolute will (invisibly) set the top to 0 causing the footer to animate starting at the top of the window. The solution is to set the current top position at the same time as position:absolute.

               
        function positionFooter() {
    
            footerHeight = $footer.outerHeight(); // include padding/margins
            footerTop = ($(window).scrollTop() + $(window).height() - footerHeight) + "px";
    
            if (($(document.body).height() + footerHeight) < $(window).height()) {
                $footer.css({
                    position: "absolute",
                    top: $footer.offset().top // include padding/margins
                }).stop().
                    animate({
                    top: footerTop
                },1000);
            } else {
                $footer.css({
                    position: "static"
                });
            }
        }
    
    
  38. yelon

    What about using pure HTML+CSS? check out http://ryanfait.com/sticky-footer/ (IE5+, and others)

  39. Dinoop
    Permalink to comment#

    I think its simply do like this

    $(function(){
    var windowHeight = $(window).height();
    var bodyHeight = $("body").outerHeight(true);
    var footerHeight = $("footer").outerHeight(true);
    
    if (windowHeight < bodyHeight){
        var footerTOP = bodyHeight - footerHeight;
        } else {
        var footerTOP = windowHeight - footerHeight;
        }
    
    $("footer").css({
            position: "absolute", top: footerTOP
       });  
    });
    
  40. Tyler
    Permalink to comment#

    I’m having an issue getting the sticky footer to add a “top: —px” value. Anyone able to take a look here:

    http://ancellcreative.com/fmm-multiculture.org/about/board-members

    and possibly give any insight? Thanks kindly!

  41. Tyler
    Permalink to comment#

    ignore my previous comment, I’ve figured out what my problem was

    Thanks again!

  42. Justin
    Permalink to comment#

    Hi Chris, just wanted to say thanks, works great, exactly what I was looking for.

    Tried several pure CSS solutions but most if not all of them required special tag layout and names/id’s, with this jquery solution it just plugged straight in and worked. Seems reliable in all browsers I have tried so far, cheers.

  43. Milski
    Permalink to comment#

    pure css sticky footer works.. until you declare a jquery link. This scripts solves that. thanks for the author.
    Im an asian so pardon my grammar.

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".