Elegant Themeable Custom Scrollbars – OverlayScrollbars

Category: Javascript , Recommended | June 23, 2024
Views Total:55 views
Official Page:Go to website
Last Update:June 23, 2024


Elegant Themeable Custom Scrollbars – OverlayScrollbars


OverlayScrollbars is a JavaScript library used to create elegant, customizable, and themeable scrollbars on any scrollable elements.

Available in Vanilla JavaScript and also can be used as a jQuery plugin.

How to use it:

1. Install the OverlayScrollbars via NPM.

$ npm install overlayscrollbars --save

2. Import the OverlayScrollbars module.

// Style
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';

3. Initialize the OverlayScrollbars.

const instance = OverlayScrollbars(document.querySelector('#myElement'), {
      // options here
// OR
  target: document.querySelector('#myElement') 
}, {
  // options here
// OR
  target: document.querySelector('#target'),
  elements: {
   viewport: document.querySelector('#viewport'),
}, {
  // options here
// OR
 target: document.querySelector('#target'),
 scrollbars: {
   slot: document.querySelector('#target').parentElement,
}, {
  // options here
// OR
 target: document.querySelector('#target'),
 cancel: {
   nativeScrollbarsOverlaid: true,
   body: null,
}, {});

4. Available options.

/** Whether the padding shall be absolute. */
paddingAbsolute: boolean;
/** Whether to show the native scrollbars. Has only an effect it the native scrollbars are overlaid. */
showNativeOverlaidScrollbars: boolean;
/** Customizes the automatic update behavior. */
update: {
   * The given Event(s) from the elements with the given selector(s) will trigger an update.
   * Useful for everything the MutationObserver and ResizeObserver can't detect
   * e.g.: and Images `load` event or the `transitionend` / `animationend` events.
  elementEvents: Array<[elementSelector: string, eventNames: string]> | null;
   * The debounce which is used to detect content changes.
   * If a tuple is provided you can customize the `timeout` and the `maxWait` in milliseconds.
   * If a single number customizes only the `timeout`.
   * If the `timeout` is `0`, a debounce still exists. (its executed via `requestAnimationFrame`).
  debounce: [timeout: number, maxWait: number] | number | null;
   * HTML attributes which will trigger an update if they're changed.
   * Basic attributes like `id`, `class`, `style` etc. are always observed and doesn't have to be added explicitly.
  attributes: string[] | null;
   * A function which makes it possible to ignore a content mutation or null if nothing shall be ignored.
   * @param mutation The MutationRecord from the MutationObserver.
   * @returns A Truthy value if the mutation shall be ignored, a falsy value otherwise.
  ignoreMutation: ((mutation: MutationRecord) => any) | null;
/** Customizes the overflow behavior per axis. */
overflow: {
  /** The overflow behavior of the horizontal (x) axis. */
  x: OverflowBehavior;
  /** The overflow behavior of the vertical (y) axis. */
  y: OverflowBehavior;
/** Customizes appearance of the scrollbars. */
scrollbars: {
   * The scrollbars theme.
   * The theme value will be added as `class` to all `scrollbar` elements of the instance.
  theme: string | null;
  /** The scrollbars visibility behavior. */
  visibility: ScrollbarsVisibilityBehavior;
  /** The scrollbars auto hide behavior. */
  autoHide: ScrollbarsAutoHideBehavior;
  /** The scrollbars auto hide delay in milliseconds. */
  autoHideDelay: number;
  /** Suspend the autoHide functionality until the first scroll interaction was performed. */
  autoHideSuspend: boolean;
  /** Whether its possible to drag the handle of a scrollbar to scroll the viewport. */
  dragScroll: boolean;
  /** Whether its possible to click the track of a scrollbar to scroll the viewport. */
  clickScroll: boolean;
   * An array of pointer types which shall be supported.
   * Common pointer types are: `mouse`, `pen` and `touch`.
   * https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pointerType
  pointers: string[] | null;

5. Event handlers.

OverlayScrollbars(document.querySelector('#myElement'), {}, {
  initialized(osInstance) {
    // ...
  updated(osInstance, onUpdatedArgs) {
    // ...
  destroyed(osInstance, canceled) {
    // ...
  scroll(osInstance, event) {
    // ...

6. API methods.

// adds new options
instance.options(optionName, optionValue)
// updates scrollbars
// returns all relevant elements.
// returns a object which describes the current state of this instance.
// removes scrollbars from DOM
// checks the current state


v2.9.0 (06/23/2024)

  • Add the possibility to define a nonce value for websites with a CSP.
  • Reduced bundle size due to removed compatiblity code.
  • clickScroll will not cancel on fast clicks / taps.
  • Add easing to the clickScroll animation.
  • The scrollbar-handle offset and size calculations are now entirely in CSS and will not force reflows.
  • Use custom css properties for setting the scrollbar-handle offset and size.
  • Bug Fixes

v2.8.0 (05/09/2024)

  • Support non default flow directions (block and inline) not only direction: rtl.
  • A new field scrollCoordinates in the State object. It indicates the min. and max. scroll coordinates for the viewport. (useful for non default flow direction scrolling)
  • A new field scrollCoordinatesChanged in the updateHints object. It indicates whether the scroll coordinates changed in an update.
  • Change zoom detection: instead of the window.resize event, the window.matchMedia event is used.
  • Greatly improve how dragging and releasing the scrollbar handle behaves for scroll-snapped viewports.
  • Bug Fixes

v2.7.0 (04/01/2024)

  • Improvements for running in deno and bun.
  • Initialization as the body element is now detected as such when the tag name of the target element is “body”. Previously this detection was done with target === target.ownerDocument.body which would not work when creating a new body element in memory.
  • If a non generated elements.viewport element is provided during initialization its scroll position will be taken as the initial scroll position instead of the scroll position of the target element.
  • When interacting with the scrollbars itself the scrollbars.autoHideDelay will now apply when the scrollbars would be auto hidden when the interaction ends.

v2.6.0 (03/09/2024)

  • Add focusin and focusout to the focus and blur event management when wrapping and unwrapping elements.
  • The scrollbars.visibility option was unintuitive to use for adjusting visibility per axis. Its now only applied if the scrollbars scroll axis is able to have a scrollable overflow.

v2.5.0 (02/01/2024)

  • Drop IE11 support.
  • Streamlining of scroll related calculations, including RTL direction.
  • Focus and Blur event management when wrapping and unwrapping elements during initialization and destroy.

v2.4.0 (10/16/2022)

  • Finalize and document the plugin system which makes it possible to create “static” and / or “instance” plugins.
  • The static OverlayScrollbars.plugin function returns a “static” plugins instance(s) for the registered plugins.
  • A new instance.plugin function which returns a “instance” plugins instance.
  • window resize events will now update instances only if it is needed and only what is needed.
  • Small internal rewrite to improve stability, performance and bundle size.

v2.3.0 (08/26/2022)

  • Make use of the new ScrollTimeline API in supported browsers.
  • Add the option scrollbars.autoHideSuspend to make it possible to suspend the autoHide functionality until the first scroll interaction was performed. The default value for this option is false for backwards compatibility reasons but is recommended to be true for better accessibility.
  • Add a CSS selector to bridge deferred initializations visually.
  • Bug Fixes

v2.2.0 (05/30/2022)

  • Force the scroll-behavior css property to be auto when the user interacts with a scrollbar to prevent smooth scrolling to apply where it shouldn’t.
  • The viewort, padding and content elements don’t use the class attribute anymore for their styling. Instead each of them uses its own data-overlayscrollbars-* attribute. This has been done so that 3rd party libraries aren’t conflicting with classnames from overlayscrollbars or vice versa. Selectors like .os-viewport, .os-padding or .os-content won’t work anymore.

v2.1.0 (02/06/2022)

  • Introduce CSS Custom Properties to improve theming and styling of scrollbars.
  • Improve pointer event handling on scrollbar handle and track.
  • Fix a bug where initial RTL direction wasn’t detected properly.

v2.0.0 (11/14/2022)

  • Major update

v1.13.3 (07/20/2022)

  • change appear animation detection from z-index to cursor.
  • only call image callback when the plugin isn’t destroyed.

v1.13.2 (06/01/2022)

  • Update

v1.13.1 (12/16/2020)

  • Fixed z-index of .os-padding
  • Fixed passive event-listeners on touch events

v1.13.0 (08/03/2020)

  • If you drag the scrollbar handle the click event won’t be propagated to the body to be closer to the native behavior.
  • The .os-padding element has now default z-index.
  • Clickscrolling amount & speed adjusts now to the scrollbar-handle size to be more accurate.
  • The RTL(right to left) style won’t be applied to the body element anymore to be closer to the native behavior.

v1.12.0 (04/06/2020)

  • ‘max-content’ is now used to detect the possible size if width is not fixed. (only if supported by the browser else the old algo. is used)
  • Updated all wrapper versions to better support frontend frameworks.
  • Removed useless touchevents from the host element
  • A new option called ‘updateOnLoad’ with which you can control on which elements / selectors OverlayScrollbars shall update automatically after the emit of a load event. Per default the value is set to [“img”] so the plugin will updated after any img emits a load event. You can set it to null to disable this auto updating entierly or add your own selectors to update only on special img elements or on for example loaded iframes.
  • Bugfixes

v1.11.0 (03/01/2020)

  • Changed RTL behavior detection to support the Chromium web interoperability effort
  • Implemented a way to intuitively set the tabindex attribute of the viewport element
  • Changed restrictedMeasuring workaround (works via CSS now).
  • Removed unnecessary CSS
  • If ResizeObserver is supported, it now detects changes in padding in Chrome again.

v1.10.3 (02/03/2020)

  • The cache of the scroll infos which can be get by the scroll method is now updated immediately after you use the scroll method to change the position.
  • Fixed: Reference Error: previousOverflow is not defined

v1.10.2 (12/31/2019)

  • Fixed a bug where the overflow wasn’t calculated properly on the newest firefox in some cases.
  • Fixed a bug where the usage of a MutationObserver in connection with zone.js freezed the browser.

v1.10.0 (10/11/2019)

  • The host element of a textarea element now applies the focus class if the textarea get focused.
  • Improved event handling & management (passive & preventDefault e.g. non-passive events)
  • The plugin now recognizes already existing DOM (helpful in component wrappers & PHP / SSR Sites)

v1.9.1 (08/03/2019)

  • Fixed a bug where the plugin didn’t update correctly if you changed interleaved options twice in a row to the same value

v1.9.0 (07/27/2019)

  • Fixed a bug where unexpected scroll jumps happened after you changed a option.
  • Fixed a bug where a min-width change wasn’t detected if width is auto
  • Fixed a bug where the update function didn’t update a textarea properly, when only its value changed and due to that its size.
  • A new global method OverlayScrollbars.valid which checks whether a passed object is a non-destroyed OverlayScrollbars instance.

v1.8.0 (07/09/2019)

  • Bugs fixed.
  • The getState() methods returned object contains now a new property called destroyed which indicates that the instance has been destroyed.
  • Changed the management of passive event listeners: touch events which call prefentDefault() are now added with passive : false, all other events which should be passive and don’t call prefentDefault() are added with passive : true.
  • Preparation for framework wrappers such as react, vue and angular: the option() method will now only cause a call to the update() method if at least one option has been truly changed.
  • Cleaner handling of the internal update() method.

v1.7.3 (06/24/2019)

  • Fixed – the status of the DOM / MutationObservers is now synchronized if you call the scroll or update function.
  • Fixed – the used MutationObserver listens now to the open attribute.
  • Fixed a bug where you can’t resize the host element when its size was 0 previously.
  • Fixed an IE8 bug where the plugin didn’t work correctly.

v1.7.2 (06/11/2019)

  • Fixed a bug where width: auto elements had incorrect width if paddingAbsolute was true.
  • OverlayScrollbars has better perfomance on Firefox now because it utilizes the new scrollbar-width CSS Property.
  • Improved perfomance on all browsers which are using natively overlaid scrollbars (mobile, OS-X etc.).
  • Changes to the textarea size measuring process, which results also in better performance if plugin is initialized on textarea elements.

v1.7.1 (05/23/2019)

  • Fixed instance.scroll({ y: “100%” }) probelm

v1.7.0 (04/18/2019)

  • A new option scrollbars.snapHandle was added which helps you to control how the scrollbar-handle behaves if you use CSS Snap Scrolling.
  • The scroll() methods returned object now has a new property called snappedHandleOffset.
  • CSS Snap Scrolling has now deeper support: The handle dragging is now smooth (controlled with the new option scrollbars.snapHandle) and the jump-back if you let go midway has now a transition.
  • If you set a handle-max-size and the overflow is way to small, the resulting jump-back if you let go midway has now a transition.
  • If you drag the handle the next calculated scroll-position is now rounded instead of floored which results in better user-experience.
  • Click scrolling is now more precise.
  • Bugs fixed.


  • v1.6.3


  • v1.6.1


  • v1.5.3


  • Remove the use of depcreated .hover() method


  • v1.5.2

You Might Be Interested In:

Leave a Reply