scroll-snap-slider

repository·main·Indexed 41 days ago

https://github.com/barthy-koeln/scroll-snap-slider

A lightweight, plugin-based slider library (v3.3.4) that leverages CSS scroll snap for native-feeling navigation. It features a core engine with extensible modules for autoplay, infinite looping, and mouse dragging, providing high performance by relying primarily on CSS.

Tokens
4.5K
Snippets
18
Records
23
Agent score
100%

What's inside scroll-snap-slider

  1. Implement the scroll-snap-slider markup and CSS

    main

    The slider requires a specific HTML structure and CSS import to function correctly.

    HTML Markup

    Use a <ul> with the class scroll-snap-slider as the container, and <li> elements with the class scroll-snap-slide for each slide.

    <ul class="scroll-snap-slider">
      <li class="scroll-snap-slide">
        <img alt="" src="https://picsum.photos/id/1011/400/300" />
      </li>
      <li class="scroll-snap-slide">
        <img alt="" src="https://picsum.photos/id/1018/400/300" />
      </li>
    </ul>

    CSS Setup

    Import the default styles in your CSS file:

    @import 'scroll-snap-slider/dist/scroll-snap-slider.css';

    To improve user experience, consider adding these styles:

    1. Prevent page navigation on horizontal scroll (e.g., macOS):
      .scroll-snap-slider {
        overscroll-behavior-x: none;
        overscroll-behavior-y: auto;
      }
    2. Prevent scrolling past elements in the slider:
      .scroll-snap-slide {
        scroll-snap-stop: always;
      }
    <ul class="scroll-snap-slider">
      <li class="scroll-snap-slide">
        <img
          alt=""
          src="https://picsum.photos/id/1011/400/300"
        />
      </li
      <li class="scroll-snap-slide">
        <img
          alt=""
          src="https://picsum.photos/id/1018/400/300"
        />
      </li
    </ul>
  2. Use ScrollSnapSlider plugins (Autoplay, Loop, Draggable)

    main

    You can extend the slider's functionality by attaching plugins using the .with() method.

    Available Plugins

    • ScrollSnapAutoplay: Automatically slides at a specified interval (milliseconds).
    • ScrollSnapLoop: Enables infinite looping (sliding past the last element returns to the first).
    • ScrollSnapDraggable: Enables mouse dragging for desktop users (does not affect touch behavior).

    Example Usage

    import { ScrollSnapSlider, ScrollSnapAutoplay, ScrollSnapLoop } from 'scroll-snap-slider';
    
    const element = document.querySelector('.example-slider')
    const slider = new ScrollSnapSlider({ element }).with([
      new ScrollSnapAutoplay(1200),
      new ScrollSnapLoop
    ])
  3. Create a custom ScrollSnapPlugin

    main

    To create a custom plugin, extend the ScrollSnapPlugin class and implement the required methods.

    Implementation Requirements

    • constructor(config): Pass configuration to the parent.
    • get id(): Return a unique string identifier for the plugin instance.
    • enable(slider): Attach listeners and initialize plugin logic using the provided slider instance.
    • disable(): Clean up resources and remove listeners.
    export class CustomPlugin extends ScrollSnapPlugin {
    
      constructor (config) {
        super()
        this.config = config
      }
    
      get id () {
        return 'lubba-wubba-dub-dub'
      }
    
      enable (slider) {
        // Implementation logic
      }
    
      disable () {
        // Cleanup logic
      }
    }
    export class CustomPlugin extends ScrollSnapPlugin {
    
      /**
       * Pass any config here
       * @param {*} config
       */
      constructor (config) {
        super()
    
        this.config = config
      }
    
      /**
       * Chose a unique plugin name.
       * @return {String}
       */
      get id () {
        return 'lubba-wubba-dub-dub'
      }
    
      /**
       * Attach listeners, fetch DOM things, save reference to the slider
       * @param {ScrollSnapSlider} slider
       * @override
       */
      enable (slider) {
        // TODO method stub
      }
    
      /**
       * Free resources, remove listeners, ...
       * @override
       */
      disable () {
        // TODO method stub
      }
    }
  4. Initialize ScrollSnapSlider with basic and advanced configuration

    main

    The ScrollSnapSlider class augments a slider element with events and methods. If you only need the CSS behavior, the JavaScript instance is optional.

    Basic Usage

    import { ScrollSnapSlider } from 'scroll-snap-slider'
    
    const element = document.querySelector('.example-slider')
    const slider = new ScrollSnapSlider({ element })

    Advanced Configuration

    Pass an options object to the constructor to customize behavior:

    • scrollTimeout: (Number) Sets the timeout to detect the end of a scroll.
    • roundingMethod: (Function) Determines when slide-pass events are dispatched. Options include Math.round (center), Math.ceil (as soon as next is visible), or Math.floor (when next is fully visible).
    • sizingMethod: (Function) A function that receives the slider instance and returns the width of a slide.
    import { ScrollSnapSlider } from 'scroll-snap-slider'
    
    const slider = new ScrollSnapSlider({
      element: document.querySelector('.example-slider'),
      scrollTimeout: 50,
      roundingMethod: Math.round,
      sizingMethod (slider) {
        return slider.element.firstElementChild.offsetWidth
      }
    })
    import { ScrollSnapSlider } from 'scroll-snap-slider'
    
    const element = document.querySelector('.example-slider')
    const slider = new ScrollSnapSlider({ element })
    
    slider.addEventListener('slide-start', function (event) {
      console.info(`Started sliding towards slide ${event.detail}.`)
    })
    
    slider.addEventListener('slide-pass', function (event) {
      console.info(`Passing slide ${event.detail}.`)
    })
    
    slider.addEventListener('slide-stop', function (event) {
      console.info(`Stopped sliding at slide ${event.detail}.`)
    })
  5. Configure quickSwipeDistance in ScrollSnapDraggable

    main

    The quickSwipeDistance option determines how much a user must drag to trigger a slide change.

    • If set to null (default): The user must drag for more than half the slider's width to reach the next or previous slide.
    • If set to a number (pixels): Dragging any slide for more than this specific pixel distance in the desired direction will trigger a slide change.
    // Requires dragging 150px to trigger a slide change
    const draggable = new ScrollSnapDraggable(150);
    
    // Requires dragging > 50% of slider width to trigger a slide change
    const draggable = new ScrollSnapDraggable(null);
  6. Configure ScrollSnapSliderOptions

    main

    When initializing ScrollSnapSlider, you can provide the following configuration options:

    OptionTypeDefaultDescription
    elementHTMLElementRequiredThe container element of the slider.
    scrollTimeoutnumber100Timeout delay in milliseconds used to detect the end of a scroll event.
    roundingMethod(value: number) => numberMath.roundFunction used to calculate the current slide index from a scroll position factor.
    sizingMethod(slider: ScrollSnapSlider, entries?: ResizeObserverEntry[]) => number(slider) => slider.element.firstElementChild.offsetWidthFunction that computes the width (in pixels) of a single slide.

    Example of custom sizing and rounding:

    const slider = new ScrollSnapSlider({
      element: container,
      scrollTimeout: 200,
      roundingMethod: Math.floor,
      sizingMethod: (slider) => {
        // Custom logic, e.g., average of all children widths
        return 300;
      }
    });
  7. Reference: ScrollSnapSlider Methods and Events

    main

    Methods

    • slideTo(index: Number): void: Scrolls to the slide at the specified index.
    • addEventListener(...): Shortcut for slider.element.addEventListener(...).
    • removeEventListener(...): Shortcut for slider.element.removeEventListener(...).
    • destroy(): Frees resources and listeners. It is recommended to set slider = null after calling this.

    Events

    Events are dispatched on the slider's element. Use the proxy addEventListener to listen to them.

    Event NameDetail TypeDescription
    slide-startNumberDispatched when sliding starts toward the slide at event.detail.
    slide-passNumberDispatched when sliding passes (crosses the threshold to) the slide at event.detail. Threshold is defined by roundingMethod.
    slide-stopNumberDispatched when sliding stops at index event.detail (last scroll event occurred before scrollTimeout ms).

    TypeScript Typing

    To get proper typing for these events, augment the global HTMLElementEventMap:

    declare global {
      interface HTMLElementEventMap {
        'slide-pass': CustomEvent<number>;
        'slide-stop': CustomEvent<number>;
        'slide-start': CustomEvent<number>;
      }
    }
  8. Reference: ScrollSnapSlider Public Properties

    main

    The following properties are available on the ScrollSnapSlider instance:

    • slide: Number (read only): The currently active slide index.
    • element: Element (read only): The DOM element passed into the constructor.
    • scrollTimeout: Number: The timeout delay in milliseconds used to detect the end of scroll events.
    • plugins: Map<String, ScrollSnapPlugin>: A map of plugins currently enabled for this slider.
  9. Listen to slider events

    main

    The ScrollSnapSlider dispatches custom events on its element. You can listen to these events to react to user interaction or state changes.

    EventDetailDescription
    slide-startnumberDispatched when a scroll begins. The detail is the index of the slide the user is moving towards.
    slide-passnumberDispatched when the slider passes a slide index during scrolling. The detail is the current active slide index.
    slide-stopnumberDispatched when scrolling has finished (after scrollTimeout). The detail is the final active slide index.

    Example:

    const el = document.querySelector('.my-slider') as HTMLElement;
    
    el.addEventListener('slide-stop', (event) => {
      const customEvent = event as CustomEvent;
      console.log('Stopped at slide:', customEvent.detail);
    });
  10. Extend functionality with plugins using .with()

    main

    The ScrollSnapSlider supports a plugin system to add additional behavior. Use the .with() method to attach an array of ScrollSnapPlugin objects.

    By default, plugins are enabled immediately upon attachment. The .with() method returns the slider instance, allowing for method chaining.

    // Assuming plugins are imported
    slider.with([pluginA, pluginB]);
    
    // Or chaining during initialization
    const slider = new ScrollSnapSlider({ element: el }).with([pluginA]);
  11. Use the ScrollSnapAutoplay plugin

    main

    The ScrollSnapAutoplay plugin automatically advances slides at a specified interval. It includes built-in logic to temporarily disable autoplay when user interactions (like touchmove or wheel) are detected, preventing the slider from fighting against the user. After a specified timeoutDuration, autoplay will automatically re-enable.

    Constructor Parameters

    ParameterTypeDefaultDescription
    intervalDurationnumber3141The duration in milliseconds between slide changes.
    timeoutDurationnumber6282The duration in milliseconds to wait after human interaction before re-enabling autoplay.
    eventsstring[]['touchmove', 'wheel']An array of event names that, when triggered on the slider, will temporarily disable autoplay.
    import { ScrollSnapAutoplay } from './lib/ScrollSnapAutoplay';
    
    // Example: Autoplay every 5 seconds, wait 10 seconds after interaction before resuming
    const autoplayPlugin = new ScrollSnapAutoplay(5000, 10000, ['touchstart', 'wheel']);
    
    // Assuming 'slider' is your initialized ScrollSnap instance
    slider.addPlugin(autoplayPlugin);