- It does not re-calculate all dimensions when scrolling, just neccessary dimensions.
- Super smooth without incurring scroll lag or jank and no page reflows.
- Integrated with resize sensor to re-calculate all dimensions of the plugin when the size of sidebar and its container is changed.
- It has event trigger on each affix type to hook your code under particular situations.
- Handle the sidebar when it is tall or too short compared to the rest of the container.
- Zero dependencies and super simple to setup.
new StickySidebar('ELEMENT') on the element that you want it to be sticky when scrolling up/down inside their parent.
Sticky sidebar is smart enough to handle sidebar when it’s taller than the viewport. You don’t have to worry about content, it will scroll the sidebar independently, up and down.
You can install sticky sidebar plugin from Bower, NPM or just simply download it from GitHub then put
sticky-sidebar.js file into your project folder.
If you are using Bower as package manager:
bower install sticky-sidebar
If you are using NPM as package manager:
npm install sticky-sidebar
Your website’s HTML structure has to be similar to this in order to work:
Note that inner sidebar wrapper
.sidebar__inner 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.
Usage with jQuery/Zepto
You can configure sticky sidebar as a jQuery plugin, just include
jquery.sticky-sidebar.js instead of
sticky-sidebar.js file than configure it as any jQuery plugin.
Make sure to include
jquery.sticky-sidebar.js script file after
Usage with ResizeSensor.js
Integrate ResizeSensor.js into sticky sidebar to detect when sidebar or container is changed. To use resize sensor with this plugin just make sure to include ResizeSensor.js before
sticky-sidebar.js code whether through module loader, bundle or event inclusion as a
<script> and enable
resizeSensor option (enabled by default) and it will work.
If you choose not to include
ResizeSensor.js, sticky sidebar will not have automatic resize detection and still continue to work without any problem.
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 styles as inline so you need to add them manually in your stylesheet.
Sticky sidebar plugin comes with options to configure how it works. All options below are optional. Default values are presented below.
Additional top spacing of the element when it becomes sticky.
Additional bottom spacing of the element when it becomes sticky.
Specify a container sidebar to limit the begin and end points of sticky element. Defaults to the closest parent of the sticky element. It is highly recommended to specify a container selector.
Inner wrapper selector of sticky sidebar, if this wrapper is not found inside sidebar element, the plugin will create one for you under class name
inner-wrapper-sticky. It is highly recommended to write inner wrapper of sidebar yourself than add its selector to this option.
If sticky sidebar has ResizeSensor.js integrated, when the size of sidebar or its container element is changed the plugin will re-calculate all dimensions. This option allows you to enable or disable resize sensor feature.
Note: This option won’t work even
ResizeSensor.js is included into your page, more details in Usage with ResizeSensor.js section.
The name of CSS class which will be added to the sidebar element when it becomes sticky.
The sidebar returns to its normal position when the width of window is below this value.
Sticky sidebar plugin has various events which are triggered when affix state changes.
affix.top.stickySidebar — Fires immediately before the element has been affixed to the top of the viewport.
affixed.top.stickySidebar — Fires immediately after the element has been affixed to the top of the viewport.
affix.bottom.stickySidebar — Fires immediately before the element has been affixed to the bottom of the viewport.
affixed.bottom.stickySidebar — Fires immediately after the element has been affixed to the bottom of the viewport.
affix.container-bottom.stickySidebar — Fires immediately before the element has been affixed to the bottom of the container.
affixed.container-bottom.stickySidebar — Fires immediately after the element has been affixed to the bottom of the container.
affix.unbottom.stickySidebar — Fires immediately before the element is no longer bottomed out.
affixed.unbottom.stickySidebar — Fires immediately after the element is no longer bottomed out.
affix.static.stickySidebar — Fires immediately before the element has returned to its position.
affixed.static.stickySidebar — Fires immediately after the element has returned to its position.
For example if you want to detect when element sticks to top and bottom we might do:
updateSticky - Force re-calculation of all cached dimensions of sidebar, container and viewport and update position of sidebar according to the new dimensions. The same function of trigger event
update.sticky, read about events above.
destroy - remove all inline styles, helper classes and event listeners.
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; that increased performance significantly, while building Sticky sidebar plugin we prevent repainting and reflow to make it as smooth as possible.
Sticky sidebar works in all modern browsers including Internet Explorer 9 and above, but if you want it to work with IE9, you should include
requestAnimationFrame polyfill before sticky sidebar code.
If you have any issue with browser compatibility, don’t hesitate to Submit an issue.
jQuery/Zepto No Conflict
Sometimes sticky sidebar plugin conflicts 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