Sticky Sidebar ⬆⬇ is a pure JavaScript plugin for making smart and high performance sticky sidebar, works with sidebar if it’s taller or shorter than the viewport, integrated with resize sensor to re-calculate the dimensions automatically when the size of sidebar or its container is changed, supports jQuery/Zepto and compatible with Firefox, Chrome, Safari, and IE9+. Source can be found on Github.
Just call 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.
For the above example, you can use the following JavaScript:
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 jquery.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.
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. Default: 0
.
Additional bottom spacing of the element when it becomes sticky. Default: 0
.
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. Default: .inner-wrapper-sticky
.
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. Default: true
.
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. Default: is-affixed
.
The sidebar returns to its normal position when the width of window is below this value. Default: 0
.
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.
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 $.fn.stickySidebar
.
Ahmed Bouhuolia GitHub/Facebook/Twitter.