Sticky Sidebar

Sticky Sidebar is jQuery plugin for making intelligent and high performance sticky sidebar, works with sidebar if it’s bigger or smaller than viewport, has resize sensor to re-calculate its dimensions automatically when size of sidebar or container is changed, supports multiply sidebars in once and compatible with Firefox, Chrome, Safari, and IE9+. Source can be found on Github.


Example

Basic

Just call $(ELEMENT).stickySidebar() on the elements that you want to be sticky when scrolling up/down inside their parent.

$('#sidebar').stickySidebar({topSpacing: 20});
Basic Demo

Basic Example

Scrollable Sticky Element

Sticky sidebar smart enough to handle sidebar when it’s taller than viewport. You don’t have to worry about content, it will scroll sidebar independently up and down.

$('#sidebar').stickySidebar({topSpacing: 20});
Scrollable Sticky Element

Scrollable Sticky Element

Multiply Sidebars

Can handle multiply sidebars, by calling $(ELEMENT1, ELEMENT2).stickySidebar() on all elements at once.

$('#sidebar, #sidebar2').stickySidebar({topSpacing: 20});
Multiply Sidebars

Or if you want to give each sidebar different options, by calling.

$(ELEMENT1).stickySidebar();
$(ELEMENT2).stickySidebar();

Multiply Sidebar


Install

You can install sticky sidebar jquery plugin from Bower, NPM or just simply download it from Github than put sticky-sidebar.js file in your project folder.

Bower

If you are using bower as package manager:

bower install sticky-sidebar

NPM

If you are using NPM as package manager:

npm install sticky-sidebar

Usage

Your website’s html structure has to be similer to this in order to work:

<div id="main-content" class="main">
    <div id="sidebar" class="sidebar">
        <div class="sidebar__inner">
            <!-- Content goes here -->
        </div>
    </div>
    <div id="content" class="content">
        <!-- Content goes here -->
    </div>
</div>

Note that inner sidebar wrapper .sidebar__innner is optional but highly recommended, if you don’t write it yourself, the script will create one for you under class name inner-wrapper-sticky. but this may cause many problems.

For the above example, you can use the following JavaScript:

<script type="text/javascript" src="./js/jquery.js"></script>
<script type="text/javascript" src="./js/sticky-sidebar.js"></script>

<script type="text/javascript">
    $(document).ready(function(){
        $("#sidebar").stickySidebar({
            containerSelector: '#main-content',
            innerWrapperSelector: '.sidebar__inner',
            topSpacing: 20,
            bottomSpacing: 20
        });	
    });
</script>

Make sure to include sticky-sidebar.js script file after jquery.js.

Via data attributes

To easily configure sticky sidebar to any element on the document using attributes, just add data-sticky-sidebar attribute with no value to element that you want to make it sticky. You can also configure its options, for example topSpacing option add it as attribute on element like that data-top-spacing="50"

Either by configure container of sticky element by adding data-sticky-sidebar-container attribute to container of sticky element. Below code will give you overview.

<div id="container" data-sticky-sidebar-container>
    <div id="#sidebar" data-sticky-sidebar data-top-spacing="50">
    	<!-- Content Goes Here -->
    </div>
    <div id="content">
    	<!-- Content Goes Here -->
    </div>
</div>	

Configure Your CSS

Next you are going to need some CSS just to improve performance and prevent repainting on scrolling. Sticky sidebar plugin doesn’t add below style as inline style so you need to add it manually in your stylesheet.

.sidebar{
    will-change: min-height;
}

.sidebar__inner{
    transform: translate(0, 0); /* For browsers don't support translate3d. */
    transform: translate3d(0, 0, 0);
    will-change: position, transform;
}

Options

Sticky sidebar plugins cames with options to configure how it works. All options below is optional.

topSpacing

Additional top spacing of the element when it becomes sticky. Default: 0.

$('#element').stickySidebar({topSpacing: 50});

bottomSpacing

Additional bottom spacing of the element when it becomes sticky. Default: 0.

$('#element').stickySidebar({bottomSpacing: 50});

containerSelector

Container sidebar selector to know what the beginning and end of sticky element. Defaults to the closest parent of the sticky element. Highly recommend to define container selector.

$('#element').stickySidebar({containerSelector: '.container'})

innerWrapperSelector

inner wrapper selector of sticky sidebar, if the plugin is not found this wrapper inside sidebar element will create one for you under class name inner-wrapper-sticky. Highly recommended to write inner wrapper of sidebar yourself than add its selector to this option. Default: .inner-wrapper-sticky.

$('#element').stickySidebar({innerWrapperSelector: '.sidebar__inner'});

resizeSensor

Sticky sidebar has resize sensor feature when size of sidebar or its container element is changed the plugin will re-calculate all dimensions. This option allow you to enable or disable resize sensor feature. Default: true.

$('#element').stickySidebar({resizeSensor: false});

stickyClass

The name of CSS class to sidebar element when it has become stuck. Default: is-affixed.

$('#element').stickySidebar({stickyClass: 'is-affixed'});

minWidth

The sidebar returns to its normal position if minimum width of window below this value. Default: 0.

$('#element').stickySidebar({minWidth: 300});

Events

Sticky sidebar jQuery plugin has various of events are trigger when changing affix state.

initialize.sticky — The event fires immediately before the sticky sidebar plugin has been initialized.

initialized.sticky — The event fires immediately after sticky sidebar plugin has been initialized.

affix-top.sticky — The event fires immdiately before the element has been affixed top of viewport.

affixed-top.sticky — The event fires immdiately after the element has been affixed top of viewport.

affix-bottom.sticky — The event fires immdiately before the element has been affixed bottom of viewport.

affixed-bottom.sticky — The event fires immdiately after the element has been affixed bottom of viewport.

affix.container-bottom.sticky — The event fires immdiately before the element has been affixed bottom of container.

affixed.container-bottom.sticky — The event fires immdiately after the element has been affixed bottom of container.

affix.unbottom.sticky — This event fires immdiately before the element is no longer bottomed out.

affixed.unbottom.sticky — This event fires immdiately after the element is no longer bottomed out.

affix.static.sticky — The event fires immdiately before the element has been returned to its position.

affixed.static.sticky — The event fires immdiately after the element has been returned to its position.

update.sticky — Trigger this event will cause force to re-calculate all cached dimentions of sticky sidebar plugin.

For example if you want to detect when element sticks top and bottom we might do:

$('.sidebar').on('affix-top.sticky', function(){
    console.log('Sidebar has stuck top of viewport.');
});

$('.sidebar').on('affix-bottom.sticky', function(event){
    console.log('Sidebar has stuck bottom of viewport.');
});

// Force to re-calculate all cached dimentions.
$('.sidebar').trigger('update.sticky');

Methods

updateSticky - Force re-calculate all cached dimensions of sidebar, container and viewport and update position of sidebar according to the new dimenstions. The same function of trigger event update.sticky read about events above.

$('.sidebar').stickySidebar('updateSticky');

destroy - remove all inline style, helper classes and event listeners.

$('.sidebar').stickySidebar('destroy');

Scrolling Performance

Sticky sidebar plugin takes scrolling preformance very seriously, It’s built from the ground up to let you have sticky elements without incurring scroll lag or jank.

The biggest cause of scrolling jank is onScroll has a lot of work. But in this plugin we cached all dimensions as well as adding will-change: transform and working with translate(Y, X) instead of top: Y; Left: X; increases performance significantly, We built Sticky sidebar plugin prevents repainting and reflow to make it smooth as much as possible.


No Conflict

Sometimes sticky sidebar plugin conflict with other plugins. In this case, namespace collisions can occasionally occur. if this happens, you may call .noConflict on the plugin to revert the value of $.fn.stickySidebar.

var stickySidebar = $.fn.stickySidebar.noConflict(); // Returns $.fn.stickySidebar assigned value.
$.fn.stickySidebar = stickySidebar; // Give $().stickySidebar functionality.

Author

Ahmed Bouhuolia GitHub/Facebook).

License

MIT License