Skip to main content

Snap

Manages carousel-like behavior. Supports

  • Tracks slide progress
  • Numerous callbacks for event handling
  • Snapping
  • Wheel interaction
  • Swipe/Drag events
  • Custom gaps with css units supported
  • Smooth transitions
  • and more...
note
  • Snap does not apply any styles to the container or slides, it only provides logic, which allows you building custom carousels.

Demo

Explore a basic demo on CodePen:

More demos

To explore more demos, click here.

Props

Static Props

Static properties are set during initialization and cannot be modified later.

container

  • Type: HTMLElement
  • Default: none
  • HTML container element where listeners are attached.

eventsEmitter

  • Type: HTMLElement | null
  • Default: null
  • HTML element used to emit events.

activeIndex

  • Type: number
  • Default: 0
  • Default active index.

Mutable Props

Mutable properties can be updated at runtime using .updateProps().

slides

  • Type: (HTMLElement | SnapSlide)[] | false;
  • Default: false
  • Slides instances. If false, all container's children will be considered as slides.

direction

  • Type: 'horizontal' | 'vertical'
  • Default: 'horizontal'
  • Sliding direction.
    See demo

centered

  • Type: boolean
  • Default: false
  • Centered slides.
    See demo

loop

  • Type: boolean
  • Default: false
  • Detects if need to loop the slides.
    See demo

gap

  • Type: number | string
  • Default: 0
  • The gap between slides. Supports css units like px, rem, vw, vh, svh.
    See demo

lerp

  • Type: number
  • Default: vevet.mobile ? 1 : 0.2
  • Linear interpolation factor for smooth animation.
    See demo

freemode

  • Type: boolean | 'sticky'
  • Default: false
  • Enables freemode, with or without sticky magnets.
    Note that you may need to disable shortSwipes when using sticky freemode.
    See demo

stickOnResize

  • Type: boolean
  • Default: true
  • Stick to the nearest slide on window resize.

friction

  • Type: number
  • Default: 0
  • Friction that makes the slides tend to the nearest slide magnet. The value is a number between 0 and 1 which is multiplied by the lerp value. 0 disables friction.
    See demo

edgeFriction

  • Type: number
  • Default: 0.85
  • Maximum friction between the final slide and the maximum translation value. From 0 to 1. The higher value the more resistance is applied.
    See demo

duration

  • Type: number | ((distance: number) => number)
  • Default: 500
  • Slide animation duration.
    See demo

easing

  • Type: TEasingType
  • Default: EaseOutCubic
  • Easing type for smoother animation. Accepts standard easing types or an array of bezier values.
    See easing types for more information
    See demo

slideSize

  • Type: 'auto' | 'stretch' | number | string
  • Default: 'auto'
  • Default slide size. Supported values:
    • auto detects slide size depending on the element or container size.
    • stretch detects slide size as the container size.
    • number defines the slide size in pixels.
    • CSS units like px, rem, vw, vh, svh.
  • Note that this property does not change real slide sizes. It is used for virtual slides & custom logic.

swipe

  • Type: boolean
  • Default: true
  • Enable or disable swipe events.

grabCursor

  • Type: boolean
  • Default: false
  • User will see the "grab" cursor when hovering and "grabbing" when swiping.
    See demo

swipeSpeed

  • Type: number
  • Default: 1
  • Speed factor for swipe movements.
    See demo

swipeAxis

  • Type: 'x' | 'y' | 'auto'
  • Default: 'auto'
  • Swipe axis. If auto, the axis will be automatically detected depending on direction.

followSwipe

  • Type: boolean
  • Default: false
  • If false, then slider will be animated only when you release the finger, it will not move while you hold your finger on it.
    See demo

shortSwipes

  • Type: boolean
  • Default: true
  • When true, swipes shorter than shortSwipeDuration can trigger slide change. Short swipes work only when followSwipe is true.

shortSwipesDuration

  • Type: number
  • Default: 300
  • Short swipe maximum duration.

shortSwipesThreshold

  • Type: number
  • Default: 30
  • Minimum distance in pixels to trigger slide change for short swipes.

swipeFriction

  • Type: boolean
  • Default: false
  • Defines if friction is allowed when swiping. Doesn't work with short swipes or when followSwipe is false.
    See demo

swipeThreshold

  • Type: number
  • Default: 5
  • Length in pixels that must be swiped to trigger swipe start.

swipeMinTime

  • Type: number
  • Default: 0
  • Minimum time in milliseconds to trigger swipe move.

swipeInertiaDuration

  • Type: (distance: number) => number
  • Default: (distance) => clamp(distance, 500, 2000)
  • Inertia duration.

swipeInertiaRatio

  • Type: number
  • Default: 0.3
  • Inertia strength.

wheel

  • Type: boolean
  • Default: false
  • Enable or disable mouse wheel control.
    See demo

wheelSpeed

  • Type: number
  • Default: 1
  • Speed factor for mouse wheel control.

wheelAxis

  • Type: 'x' | 'y' | 'auto'
  • Default: 'auto'
  • Wheel axis. If auto, the axis will be automatically detected depending on direction.
    See demo

followWheel

  • Type: boolean
  • Default: true
  • If false, disables smooth, continuous scrolling behavior from the mouse wheel and instead updates the snap position in discrete steps (like pagination).
    See demo

wheelThrottle

  • Type: number | 'auto'
  • Default: auto
  • Throttle wheel events, value in milliseconds. Works only if followWheel is disabled.

stickOnWheelEnd

  • Type: boolean
  • Default: true
  • Enable snapping on wheel stop. Works with followWheel enabled.
    See demo

stickOnWheelEndThreshold

  • Type: number
  • Default: 30
  • Snapping threshold for stickOnWheelEnd.

Accessors

note

All Module's accessors are available in this class.

activeIndex

Type: number

Active slide index

activeSlide

Type: SnapSlide

Active slide

axis

Type: "x" | "y"

Get axis name depending on direction

container

Type: HTMLElement

Get container

domSize

Type: number

Container size depending on direction (width or height)

eventsEmitter

Type: HTMLElement

Get events emitter

firstSlideSize

Type: number

Get first slide size

isEmpty

Type: boolean

Defines if there's nothing to animate

isTransitioning

Type: boolean

If transition in progress

scrollableSlides

Type: SnapSlide[]

Scrollable slides (which size is larger than the container)

slides

Type: SnapSlide[]

All slides

track.canLoop

Type: boolean

If can loop

track.current

Type: number

Gets/sets the current track value.

track.isEnd

Type: boolean

If the end has been reached

track.isInterpolated

Type: boolean

Whether the track is interpolated

track.isSlideScrolling

Type: boolean

Check if the active slide is larger than the container and is being scrolled

track.isStart

Type: boolean

If the start has been reached

track.loopCount

Type: number

Get loop count

track.loopedCurrent

Type: number

Get looped current value

track.max

Type: number

Get maximum track value

track.min

Type: number

Get minimum track value

track.offset

Type: number

Get track offset

track.progress

Type: number

Get track progress. From 0 to 1 if not loop. From -Infinity to Infinity if loop

track.target

Type: number

Gets/sets the target track value

track.influence

Type: number

Gets/sets current->target influence caused by swipe or wheel input.

Methods

note

All Module's methods are available in this class.

cancelTransition

Cancel sticky behavior

instance.cancelTransition();

next

Go to next slide

instance.next({ duration: 500, skip: 1 });

prev

Go to previous slide

instance.prev({ duration: 500, skip: 1 });

render

Force slides rendering

instance.render();

resize

Request resize (handled with debounce timeout)

instance.resize(true);

stick

Stick to the nearest magnet

instance.stick();

toCoord

Go to a definite coordinate

instance.toCoord(1365, { duration: 250 });

toSlide

Go to a slide by index

instance.toSlide(1, { direction: 'next', duration: 500 });

track.clampTarget

Clamp target value between min and max values

instance.track.clampTarget();

track.iterateTarget

Iterate track target value

instance.track.iterateTarget(50);

track.loopCoord

Loop a coordinate if can loop

instance.track.loop(1234);

track.lerp

Interpolate the current track value

instance.track.lerp(0.1);

track.set

Set current & target value instantly

instance.track.set(1350);

getNearestMagnet

Get nearest magnet to the current position

const magnet = instance.getNearestMagnet(1234);

Callbacks

note

All Module's callbacks are available in this class.

activeSlide

Triggered on active slide change

const destruct = instance.on('activeSlide', (slide) => console.log(slide.index));

// Cancel the callback
destruct();

rafPause

Triggered on requestAnimationFrame pause

const destruct = instance.on('rafPause', () => console.log('pause'));

// Cancel the callback
destruct();

rafPlay

Triggered on requestAnimationFrame play

const destruct = instance.on('rafPlay', () => console.log('play'));

// Cancel the callback
destruct();

reflow

Triggered on carousel calculation

const destruct = instance.on('reflow', () => console.log('reflow'));

// Cancel the callback
destruct();

### `resize`

Triggered on carousel resize

```ts
const destruct = instance.on('resize', () => console.log('resize'));

// Cancel the callback
destruct();

swipe

Triggered on swipe move

const destruct = instance.on('swipe', (coord) => console.log(coord));

// Cancel the callback
destruct();

swipeEnd

Triggered on swipe end

const destruct = instance.on('swipeEnd', (coord) => console.log(coord));

// Cancel the callback
destruct();

swipeStart

Triggered on swipe start

const destruct = instance.on('swipeStart', (coord) => console.log(coord));

// Cancel the callback
destruct();

timelineEnd

Triggered on timeline animation end

const destruct = instance.on('timelineEnd', () => console.log('end'));

// Cancel the callback
destruct();

timelineStart

Triggered on timeline animation start

const destruct = instance.on('timelineStart', () => console.log('start'));

// Cancel the callback
destruct();

timelineUpdate

Triggered on timeline animation progress update

const destruct = instance.on('timelineUpdate', ({ progress, eased }) => {
console.log(progress, eased);
});

// Cancel the callback
destruct();

update

Triggered on carousel coords update

const destruct = instance.on('update', () => console.log('update'));

// Cancel the callback
destruct();

wheel

Triggered on wheel event

const destruct = instance.on('wheel', (evt) => console.log(evt));

// Cancel the callback
destruct();

wheelEnd

Triggered on wheel events end

const destruct = instance.on('wheelEnd', () => console.log('end'));

// Cancel the callback
destruct();

wheelStart

Triggered on wheel events start

const destruct = instance.on('wheelStart', () => console.log('start'));

// Cancel the callback
destruct();

swipeInertiaStart

Triggered on swipe inertia start

const destruct = instance.on('swipeInertiaStart', () => console.log('start'));

// Cancel the callback
destruct();

swipeInertiaEnd

Triggered on swipe inertia end

const destruct = instance.on('swipeInertiaEnd', () => console.log('end'));

// Cancel the callback
destruct();

swipeInertiaCancel

Triggered on swipe inertia cancel

const destruct = instance.on('swipeInertiaCancel', () => console.log('cancel'));

// Cancel the callback
destruct();

swipeInertiaFail

Triggered on swipe inertia fail

const destruct = instance.on('swipeInertiaFail', () => console.log('fail'));

// Cancel the callback
destruct();

Parallax

Snap does not modify element styles by default, but it provides a set of optional parallax utilities for DOM elements.

Parallax effects are enabled using data- attributes.

Parallax Effects

Each parallax attribute maps directly to a corresponding CSS transform (or opacity):

  • data-snap-parallax-x -> translateX()
  • data-snap-parallax-y -> translateY()
  • data-snap-parallax-z -> translateZ()
  • data-snap-parallax-scale -> scale() - value is added to 1
  • data-snap-parallax-scale-x -> scaleX() - value is added to 1
  • data-snap-parallax-scale-y -> scaleY() - value is added to 1
  • data-snap-parallax-skew -> skew()
  • data-snap-parallax-skew-x -> skewX()
  • data-snap-parallax-skew-y -> skewY()
  • data-snap-parallax-rotate -> rotate()
  • data-snap-parallax-rotate-x -> rotateX()
  • data-snap-parallax-rotate-y -> rotateY()
  • data-snap-parallax-rotate-z -> rotateZ()
  • data-snap-parallax-opacity -> opacity - should contain negative values only, decreasing the current opacity.

All effect attributes accept numbers or any supported CSS unit.

Parallax Timeline

By default, parallax values are applied while the slide transition progress is between -1 and 1.

You can inspect slide progress in this demo.

To change the active range, use the data-snap-parallax-scope attribute:

  • numeric range like data-snap-parallax-scope="-2, 2"
  • infinite range like data-snap-parallax-scope="-Infinity, Infinity"

The scope applies to all parallax effects inside a slide unless overridden per effect:

data-snap-parallax-y-scope="-2, 2"

Parallax Strength

Use data-snap-parallax-[effect]-influence to apply the effect only during dragging or wheeling.

The parallax value will smoothly increase or decrease based on interaction intensity, producing more "organic" motion.

Positive Values

data-snap-parallax-[effect]-abs forces the effect to use absolute (non-negative) values.

This is useful for properties like scale() where negative values are undesirable.

Parallax example

Organic Gap:

<div className="slide">
<div
className="wrap"
data-snap-parallax-x="-200%"
data-snap-parallax-x-scope="-Infinity, Infinity"
data-snap-parallax-x-influence
>
Slide Info
</div>
</div>

Scale:

<div className="slide">
<div
className="wrap"
data-snap-parallax-opacity="-0.33"
data-snap-parallax-opacity-scope="-4,4"
>
Slide Info
</div>
</div>