SmartSlimScroll.js

Smooth Scrolling, No Drama!

SmartSlimScroll.js is a lightweight, high-performance JavaScript library that replaces the browser's default scrollbars with elegant, customizable slim scrollbars. It enhances the user experience with smooth scrolling, touch support, and a modern look while maintaining accessibility and performance.

Pro Tip: SmartSlimScroll.js is built with security and performance in mind, featuring input sanitization, event throttling, and passive event listeners for smooth scrolling even on low-end devices.

Installation

Include the SmartSlimScroll.js script in your HTML file:

<script src="path/to/smartSlimscroll.js"></script>

Basic initialization

// Initialize with default options
new smartSlimScroll('#content-container');

// Or with custom options
new smartSlimScroll('#content-container', {
    height: '400px',
    size: '8px',
    color: '#4285f4',
    position: 'right',
    alwaysVisible: true
});

HTML Structure

<div id="content-container" style="height: 300px;">
    <!-- Your scrollable content here -->
    <p>Lorem ipsum dolor sit amet...</p>
    <p>More content...</p>
</div>
Important: The target element should have a fixed height or a max-height set either via CSS or through the plugin options. Without a defined height, the scrollbar won't appear.

Configuration Options

SmartSlimScroll.js offers extensive configuration options to customize its appearance and behavior:

Option Default Value Description Type
width 'auto' Width of the scrollable area. 'auto' uses the element's width. string
height '250px' Height of the scrollable area. string
size '7px' Width of the scrollbar. string
color '#000' Color of the scrollbar. string
position 'right' Position of the scrollbar ('right' or 'left'). string
offsetX '1px' Horizontal offset of the scrollbar from the edge. string
offsetY '0px' Vertical offset of the scrollbar from the top. string
start 'top' Initial scroll position ('top', 'bottom', or a CSS selector). string
opacity 0.4 Opacity of the scrollbar when visible. number
fadeOutSpeed 500 Time in milliseconds for the scrollbar to fade out. number
alwaysVisible false Whether the scrollbar should always be visible. boolean
disableFadeOut false Prevents the scrollbar from fading out after use. boolean
railVisible false Whether the scrollbar rail should be visible. boolean
railColor '#333' Color of the scrollbar rail. string
railOpacity 0.2 Opacity of the scrollbar rail when visible. number
railClass 'slimScrollRail' CSS class for the scrollbar rail. string
barClass 'slimScrollBar' CSS class for the scrollbar. string
wrapperClass 'slimScrollDiv' CSS class for the wrapper element. string
allowPageScroll false Whether to allow the page to scroll when reaching the end of the content. boolean
wheelStep 20 Scroll distance for each mouse wheel step (in percentage). number
touchScrollStep 200 Scroll distance for touch events. number
borderRadius '7px' Border radius of the scrollbar. string
railBorderRadius '7px' Border radius of the scrollbar rail. string

Advanced Configuration Example

Here's an example of how to configure SmartSlimScroll with advanced options:

new smartSlimScroll('#content-container', {
    width: '100%',
    height: '500px',
    size: '10px',
    color: '#4285f4',
    position: 'right',
    offsetX: '2px',
    offsetY: '5px',
    start: '#section-2', // Scroll to an element with id "section-2"
    opacity: 0.7,
    fadeOutSpeed: 1000,
    alwaysVisible: false,
    disableFadeOut: false,
    railVisible: true,
    railColor: '#e0e0e0',
    railOpacity: 0.5,
    railClass: 'custom-rail',
    barClass: 'custom-bar',
    wrapperClass: 'custom-wrapper',
    allowPageScroll: false,
    wheelStep: 10,
    touchScrollStep: 100,
    borderRadius: '5px',
    railBorderRadius: '5px'
});

Key Features

Security Enhancements

  • Input Sanitization: All user-provided options are sanitized to prevent XSS attacks
  • Bounds Checking: Touch and scroll inputs are validated to prevent manipulation
  • Safe DOM Manipulation: Uses modern DOM APIs with proper validation

Performance Optimizations

  • Event Throttling: Scroll and touch events are throttled to improve performance
  • Passive Event Listeners: Uses passive listeners where appropriate for smoother scrolling
  • Intersection Observer: Uses modern APIs to efficiently check element visibility
  • Efficient DOM Operations: Minimizes reflows and repaints

Memory Management

  • WeakMap for State: Uses WeakMap for private state to prevent memory leaks
  • Proper Cleanup: Includes a destroy method to remove event listeners and DOM elements
  • Event Listener Management: Properly removes event listeners to prevent memory leaks
Pro Tip: The use of WeakMap for private state management ensures that memory is automatically reclaimed when elements are removed from the DOM, preventing memory leaks in long-running applications.

Usage Examples

Basic Usage

// Initialize with default options
new smartSlimScroll('#content-container');

Multiple Elements

// Initialize on multiple elements with the same options
new smartSlimScroll('.scrollable-content', {
    height: '300px',
    color: '#4285f4'
});

Different Positions

// Left-positioned scrollbar
new smartSlimScroll('#left-content', {
    position: 'left',
    color: '#db4437'
});

// Right-positioned scrollbar (default)
new smartSlimScroll('#right-content', {
    position: 'right',
    color: '#0f9d58'
});

Always Visible Scrollbar

// Scrollbar that never fades out
new smartSlimScroll('#important-content', {
    alwaysVisible: true,
    opacity: 0.8,
    color: '#4285f4'
});

Custom Styling

// Fully customized scrollbar
new smartSlimScroll('#styled-content', {
    size: '12px',
    color: 'rgba(66, 133, 244, 0.8)',
    railVisible: true,
    railColor: 'rgba(0, 0, 0, 0.1)',
    borderRadius: '6px',
    railBorderRadius: '6px'
});

Event Handling

SmartSlimScroll.js handles various user interaction events:

// Mouse wheel events
wrapper.addEventListener('wheel', handleWheel, { 
    passive: false, 
    capture: true 
});

// Touch events
wrapper.addEventListener('touchmove', handleTouchMove, { 
    passive: false, 
    capture: true 
});

// Mouse drag events
bar.addEventListener('mousedown', onMouseDown);

// Mouse hover events
wrapper.addEventListener('mouseenter', function() {
    state.isOverPanel = true;
    showBar();
});

// Rail click events
rail.addEventListener('mousedown', function(e) {
    // Calculate and scroll to clicked position
});

The scrollbar responds to the following interactions:

  • Mouse wheel: Scrolls the content up or down
  • Touch movement: Scrolls the content on touch devices
  • Scrollbar drag: Allows direct manipulation of the scrollbar
  • Rail click: Jumps to the clicked position
  • Mouse hover: Shows the scrollbar when hovering over the content

Scrollbar Visibility

SmartSlimScroll.js intelligently manages scrollbar visibility:

// Show scrollbar
var showBar = function() {
    getBarHeight();
    clearTimeout(state.queueHide);

    // Show bar if content is scrollable and we're either:
    // 1. Over the content panel
    // 2. Over the bar/rail
    // 3. Currently dragging
    // 4. Currently scrolling
    if (me.scrollHeight > wrapper.offsetHeight && 
        (state.isOverPanel || state.isOverBar || state.isOverRail || state.isDragg || state.isScrolling)) {
        bar.style.opacity = o.opacity;
        rail.style.opacity = o.railOpacity;

        // If only hovering over panel (not interacting), hide after delay
        if (state.isOverPanel && 
            !state.isOverBar && 
            !state.isOverRail && 
            !state.isDragg && 
            !state.isScrolling) {
            clearTimeout(state.queueHide);
            state.queueHide = setTimeout(function() {
                hideBar();
            }, o.fadeOutSpeed);
        }
    }
};

The scrollbar visibility is controlled by:

  • Mouse hover: Shows when hovering over the content
  • Interaction: Shows during scrolling or dragging
  • Fade out: Automatically fades out after a delay
  • Configuration: Can be set to always visible
  • Intersection Observer: Shows/hides based on element visibility in viewport
Pro Tip: For important content where users need to be aware of scrollability, set alwaysVisible: true to ensure the scrollbar is always visible.

Cleanup and Destruction

SmartSlimScroll.js provides a clean way to remove the custom scrollbar and restore the original element:

// Get the instance
var scroll = new smartSlimScroll('#content-container');

// Later, when you want to destroy it:
scroll.destroy();

The destroy method:

  • Removes all event listeners to prevent memory leaks
  • Disconnects the Intersection Observer
  • Removes the custom scrollbar elements from the DOM
  • Restores the original element to its pre-initialization state
  • Cleans up internal state and references
Important: Always call the destroy() method before removing elements with SmartSlimScroll from the DOM to prevent memory leaks, especially in single-page applications.

Best Practices

  • Always specify a height for the container element, either via CSS or the plugin options
  • For touch devices, consider increasing the touchScrollStep value for better usability
  • Use alwaysVisible: true for content where scrollability needs to be obvious
  • For dark themes, use lighter scrollbar colors with higher opacity for better visibility
  • Call destroy() when removing elements from the DOM to prevent memory leaks
  • Use the railVisible option to provide better visual cues for scrollable areas
Pro Tip: For the best user experience, match the scrollbar color to your application's accent color and use a subtle, semi-transparent rail color to indicate the scrollable area.

Troubleshooting

Common Issues:
  • Scrollbar not appearing? Ensure your container has a fixed height and contains content that exceeds this height.
  • Scrollbar not working on mobile? Check that touch events are not being prevented by other scripts or CSS properties like touch-action: none.
  • Content not scrollable? Verify that the content's height is correctly calculated and exceeds the container's height.
  • Performance issues? Reduce the complexity of the scrollable content or increase the fadeOutSpeed to reduce animation overhead.
  • Memory leaks? Ensure you call destroy() when removing elements with SmartSlimScroll from the DOM.