Install scroll-snap-slider
mainYou can install the package using npm or yarn.
npm install scroll-snap-slider
yarn add scroll-snap-slidernpm install scroll-snap-slider
yarn add scroll-snap-sliderrepository·main·Indexed 41 days ago
https://github.com/barthy-koeln/scroll-snap-sliderA 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.
You can install the package using npm or yarn.
npm install scroll-snap-slider
yarn add scroll-snap-slidernpm install scroll-snap-slider
yarn add scroll-snap-sliderThe slider requires a specific HTML structure and CSS import to function correctly.
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>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:
.scroll-snap-slider {
overscroll-behavior-x: none;
overscroll-behavior-y: auto;
}.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>You can extend the slider's functionality by attaching plugins using the .with() method.
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).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
])To create a custom plugin, extend the ScrollSnapPlugin class and implement the required methods.
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
}
}The ScrollSnapSlider class augments a slider element with events and methods. If you only need the CSS behavior, the JavaScript instance is optional.
import { ScrollSnapSlider } from 'scroll-snap-slider'
const element = document.querySelector('.example-slider')
const slider = new ScrollSnapSlider({ element })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}.`)
})The quickSwipeDistance option determines how much a user must drag to trigger a slide change.
null (default): The user must drag for more than half the slider's width to reach the next or previous slide.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);When initializing ScrollSnapSlider, you can provide the following configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
element | HTMLElement | Required | The container element of the slider. |
scrollTimeout | number | 100 | Timeout delay in milliseconds used to detect the end of a scroll event. |
roundingMethod | (value: number) => number | Math.round | Function used to calculate the current slide index from a scroll position factor. |
sizingMethod | (slider: ScrollSnapSlider, entries?: ResizeObserverEntry[]) => number | (slider) => slider.element.firstElementChild.offsetWidth | Function 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;
}
});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 are dispatched on the slider's element. Use the proxy addEventListener to listen to them.
| Event Name | Detail Type | Description |
|---|---|---|
slide-start | Number | Dispatched when sliding starts toward the slide at event.detail. |
slide-pass | Number | Dispatched when sliding passes (crosses the threshold to) the slide at event.detail. Threshold is defined by roundingMethod. |
slide-stop | Number | Dispatched when sliding stops at index event.detail (last scroll event occurred before scrollTimeout ms). |
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>;
}
}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.The ScrollSnapSlider dispatches custom events on its element. You can listen to these events to react to user interaction or state changes.
| Event | Detail | Description |
|---|---|---|
slide-start | number | Dispatched when a scroll begins. The detail is the index of the slide the user is moving towards. |
slide-pass | number | Dispatched when the slider passes a slide index during scrolling. The detail is the current active slide index. |
slide-stop | number | Dispatched 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);
});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]);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.
| Parameter | Type | Default | Description |
|---|---|---|---|
intervalDuration | number | 3141 | The duration in milliseconds between slide changes. |
timeoutDuration | number | 6282 | The duration in milliseconds to wait after human interaction before re-enabling autoplay. |
events | string[] | ['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);