Fixed Scroll Navigation with MooTools

sticky navigation bar that remains fixed on scrolling

The Goal#

Currently a very popular and often used technique wich provides a great usability. There are a several jQuery plugins and code-snippets available which are providing this feature but they are sometimes very complex and didn’t work with MooTools based websites. This tutorial shows you how to create a sticky navigation bar that remains fixed on scrolling with MooTools.

It’s not Magic#

The trick behind is very very simple: you need a small piece of javascript which observes the windows scroll position – if it’s greater then the top-border-position of our Navigation-Container it will be switch it’s positioning to fixed or vice versa to position: relative which means the container will be positioned depending on it’s parent. You can achieve these style-change by simply adding/removing an additional class with the position: fixed; rule set.

Some Code#

HTML Container Structure#

The structure is very simple, you only need a container for your sidebar which is normal positioned in your layout. This example e.g. usees Bootstraps Grid-Layout to create a right-aligned sidebar. The content/elements of your Content-Navigation can be created using javascript or with your backend-software.

<div id="page" class="row">
   <!-- Bootstrap Grid !-->
   <div class="col-lg-10">
      <div id="contentpane">....</div>
   </div>

   <div class="col-lg-2">
      <div id="contentnavi">
         <ul>....</ul>
      </div>
   </div>
</div>

CSS Setup#

The basic styling of your navigation container. It’s very important to leave settings for left/right blank! – the fixed container will be positioned relativly to it’s parent container position (the column layout will be set it’s left-position).

#contentnavi{
    display: block;
    position: relative;
    /* top value on start */
    top: 120px;
    left: auto;
    height: auto;
    width: 200px;
}
#contentnavi.fixedPosition{
    position: fixed;
    /* top value on fixed position - this value should be set to your headers height+offset */
    top: 80px;
}

The Observer#

First of all we need to fetch the initial top-value of the Navigation-Container var scrollLimit = .. which is set by the stylesheet – you can also use a static value but this solution is more dynamic (changing styles). The real magic is done in the next view lines: we’re listening on the browsers scroll event and get the current, absolute y-scroll value of the window object with this.getScroll().y – if this value is greater then our scrollLimit (which means that the user as scrolled to the upper border of our Navigation-Container) the css-class fixedPosition is added to the container, which forces position: fixed and results in a fixed navigation. if the value is lower, the class will be removed and the default position: relative setting is used!

window.addEvent('domready', function(){
    // navi container element
    var naviContainer = document.id('contentnavi');
    
    // initial scroll offset
    // get absolute container position
    var scrollLimit = naviContainer.getPosition().y;
    
    // get fixed position and use this value as offset
    naviContainer.addClass('fixedPosition');
    scrollLimit = scrollLimit - naviContainer.getStyle('top').toInt();
    naviContainer.removeClass('fixedPosition'); 
    
    // fixed sidebar
    window.addEvent('scroll', function(){
        if (this.getScroll().y > scrollLimit){
            naviContainer.addClass('fixedPosition');
        }else{
            naviContainer.removeClass('fixedPosition');
        }
    });
});