Nathan McGinness

Fixed positions with JavaScript

Fixed elements (sidebars in particular) are becoming popular. You know those sidebars that wait until the top of window hits them, and they magically stick?

In simple situations (this site for example) CSS will do the trick. But what if dynamic content at the top of your page changes this calculation (a flash or notification message for example)? Or your header likes to change size?

Ozan helped me solve this problem, and I thought I’d share.

We’ll start by selecting said element, calling our custom function, and specifying how far from the top of the page it lives:

$('#fixed').myFixture({ topBoundary: 20 });

And our function looks something like this:

$.fn.myFixture = function (settings) {
  return this.each(function () {
    
    // default css declaration 
    var elem = $(this).css('position', 'fixed');
    
    var setPosition = function () {         
      var top = 0;
      // get no of pixels hidden above the the window     
      var scrollTop = $(window).scrollTop();    
      // get elements distance from top of window
      var topBuffer = ((settings.topBoundary || 0) - scrollTop);
      // update position if required
      if (topBuffer >= 0) { top += topBuffer }
      elem.css('top', top);      
    };
        
    $(window).bind('scroll', setPosition);
    setPosition();
  });
};

Let’s revisit our first block of code, and base the calculation on the height of a header element above it:

var header = $('header')
  , topBoundary = header.outerHeight();
$('#fixed').myFixture({ topBoundary: topBoundary });

Another (even more flexible) approach would be to make topBoundary equal to the offset().top of the #fixed element on load.

Enjoy!

blog comments powered by Disqus