Customize scrollbar in modern browsers with smooth scrolling experience.
npx @tessl/cli install tessl/npm-smooth-scrollbar@8.8.0Smooth Scrollbar is a customizable, flexible, and high-performance scrollbar library for modern browsers that enables developers to replace native scrollbars with smooth-scrolling custom implementations. It offers extensive customization options through CSS styling, plugin system support, and comprehensive APIs for controlling scrolling behavior, momentum, and overscroll effects.
npm install smooth-scrollbarimport Scrollbar from "smooth-scrollbar";For CommonJS:
const Scrollbar = require("smooth-scrollbar");UMD (browser):
<script src="dist/smooth-scrollbar.js"></script>import Scrollbar from "smooth-scrollbar";
// Initialize scrollbar on a DOM element
const container = document.querySelector("#my-scrollbar");
const scrollbar = Scrollbar.init(container, {
damping: 0.1,
thumbMinSize: 20,
renderByPixels: true,
alwaysShowTracks: false,
continuousScrolling: true
});
// Initialize on all elements with data-scrollbar attribute
const scrollbars = Scrollbar.initAll();
// Listen to scroll events
scrollbar.addListener((status) => {
console.log(`Scroll position: x=${status.offset.x}, y=${status.offset.y}`);
});
// Programmatic scrolling
scrollbar.scrollTo(0, 100, 300); // x, y, duration in msSmooth Scrollbar is built around several key components:
Primary interface for creating, managing, and destroying scrollbar instances. Provides both single-element and batch operations.
class SmoothScrollbar {
static version: string;
static ScrollbarPlugin: typeof ScrollbarPlugin;
static init(elem: HTMLElement, options?: Partial<ScrollbarOptions>): Scrollbar;
static initAll(options?: Partial<ScrollbarOptions>): Scrollbar[];
static has(elem: HTMLElement): boolean;
static get(elem: HTMLElement): Scrollbar | undefined;
static getAll(): Scrollbar[];
static destroy(elem: HTMLElement): void;
static destroyAll(): void;
static use(...Plugins: (typeof ScrollbarPlugin)[]): void;
static attachStyle(): void;
static detachStyle(): void;
}Individual scrollbar instance methods for precise control over scrolling behavior, position, and state.
interface Scrollbar {
readonly containerEl: HTMLElement;
readonly contentEl: HTMLElement;
readonly options: ScrollbarOptions;
readonly size: ScrollbarSize;
readonly offset: Data2d;
readonly limit: Data2d;
scrollTop: number;
scrollLeft: number;
destroy(): void;
update(): void;
scrollTo(x?: number, y?: number, duration?: number, options?: Partial<ScrollToOptions>): void;
setPosition(x?: number, y?: number, options?: Partial<SetPositionOptions>): void;
scrollIntoView(elem: HTMLElement, options?: Partial<ScrollIntoViewOptions>): void;
addListener(fn: ScrollListener): void;
removeListener(fn: ScrollListener): void;
}Extensible plugin architecture for adding custom behaviors like overscroll effects, custom easing, or specialized scrolling modes.
class ScrollbarPlugin {
static pluginName: string;
static defaultOptions: any;
readonly scrollbar: Scrollbar;
readonly options: any;
readonly name: string;
onInit(): void;
onDestroy(): void;
onUpdate(): void;
onRender(remainMomentum: Data2d): void;
transformDelta(delta: Data2d, evt: Event): Data2d;
}Advanced momentum control for natural scrolling physics with customizable easing and momentum manipulation.
interface Scrollbar {
addMomentum(x: number, y: number): void;
setMomentum(x: number, y: number): void;
addTransformableMomentum(
x: number,
y: number,
fromEvent: Event,
callback?: AddTransformableMomentumCallback
): void;
}
interface AddTransformableMomentumCallback {
(this: Scrollbar, willScroll: boolean): void;
}interface ScrollbarOptions {
damping: number;
thumbMinSize: number;
renderByPixels: boolean;
alwaysShowTracks: boolean;
continuousScrolling: boolean;
delegateTo: EventTarget | null;
wheelEventTarget: EventTarget | null; // deprecated
plugins: any;
}
interface Data2d {
x: number;
y: number;
}
interface ScrollbarSize {
container: Metrics;
content: Metrics;
}
interface Metrics {
width: number;
height: number;
}
interface ScrollStatus {
offset: Data2d;
limit: Data2d;
}
interface ScrollListener {
(this: Scrollbar, status: ScrollStatus): void;
}
interface TrackController {
readonly xAxis: ScrollbarTrack;
readonly yAxis: ScrollbarTrack;
update(): void;
autoHideOnIdle(): void;
}
interface ScrollbarTrack {
readonly element: HTMLElement;
readonly thumb: ScrollbarThumb;
show(): void;
hide(): void;
update(offset: number, containerSize: number, contentSize: number): void;
attachTo(element: HTMLElement): void;
}
interface ScrollbarThumb {
readonly element: HTMLElement;
displaySize: number;
realSize: number;
offset: number;
attachTo(track: HTMLElement): void;
update(scrollOffset: number, containerSize: number, pageSize: number): void;
}