Media Carousel

Carousel

A scroll-snap carousel that wraps your .wf-carousel-item children in a scrollable track. Supports navigation arrows, pagination dots, autoplay, mouse drag, multi-slide-per-page, and vertical orientation — all through data attributes. The programmatic API is available on el._wfCarousel after the component initializes.

Basic Carousel

Minimal Setup

Add data-wf-carousel to a .wf-carousel wrapper containing .wf-carousel-item children. Mouse drag and touch scroll are enabled by default — no further options are required.

HTML
<div class="wf-carousel" data-wf-carousel>
    <div class="wf-carousel-item"><img src="slide-1.jpg" alt="Slide 1"></div>
    <div class="wf-carousel-item"><img src="slide-2.jpg" alt="Slide 2"></div>
    <div class="wf-carousel-item"><img src="slide-3.jpg" alt="Slide 3"></div>
</div>

Navigation & Pagination

Arrows, Dots & Loop

data-wf-navigation adds prev/next arrow buttons. data-wf-pagination adds clickable dot indicators below the track. data-wf-loop wraps from the last slide back to the first. Without a loop, arrow buttons disable automatically at the boundaries.

HTML
<div class="wf-carousel" data-wf-carousel
     data-wf-navigation
     data-wf-pagination
     data-wf-loop>
    <div class="wf-carousel-item"><img src="slide-1.jpg" alt="Slide 1"></div>
    <div class="wf-carousel-item"><img src="slide-2.jpg" alt="Slide 2"></div>
    <div class="wf-carousel-item"><img src="slide-3.jpg" alt="Slide 3"></div>
</div>

Multiple Slides Per Page

Visible Slides & Scroll Step

data-wf-slides-per-page sets how many slides are visible simultaneously — slide width is calculated automatically. Use data-wf-slides-per-page-sm to override on narrow viewports (< 42rem). data-wf-slides-per-move controls how many slides the prev/next buttons advance per click.

HTML
<div class="wf-carousel" data-wf-carousel
     data-wf-navigation
     data-wf-pagination
     data-wf-slides-per-page="3"
     data-wf-slides-per-page-sm="1"
     data-wf-slides-per-move="1">
    <div class="wf-carousel-item"><img src="slide-1.jpg" alt="Slide 1"></div>
    <div class="wf-carousel-item"><img src="slide-2.jpg" alt="Slide 2"></div>
    <div class="wf-carousel-item"><img src="slide-3.jpg" alt="Slide 3"></div>
    <!-- more items -->
</div>

Autoplay

Auto-Advance

data-wf-autoplay starts auto-advancing after init. data-wf-autoplay-interval sets the delay in milliseconds (default 3000, minimum 500). Autoplay pauses automatically on hover and focus and resumes when the pointer leaves. Use data-wf-loop alongside autoplay to prevent stopping at the last slide.

HTML
<div class="wf-carousel" data-wf-carousel
     data-wf-navigation
     data-wf-pagination
     data-wf-loop
     data-wf-autoplay
     data-wf-autoplay-interval="3000">
    <div class="wf-carousel-item"><img src="slide-1.jpg" alt="Slide 1"></div>
    <div class="wf-carousel-item"><img src="slide-2.jpg" alt="Slide 2"></div>
    <div class="wf-carousel-item"><img src="slide-3.jpg" alt="Slide 3"></div>
</div>

Vertical Orientation

Column Layout

Set data-wf-orientation="vertical" to switch to a column flex layout. Slide height is controlled by --wf-carousel-slide-height (default: 300px). Navigation buttons move to the top and bottom edges; pagination dots stack vertically at the inline-end edge.

HTML
<div class="wf-carousel" data-wf-carousel
     data-wf-orientation="vertical"
     data-wf-navigation
     data-wf-pagination
     style="--wf-carousel-slide-height:300px;">
    <div class="wf-carousel-item"><img src="slide-1.jpg" alt="Slide 1"></div>
    <div class="wf-carousel-item"><img src="slide-2.jpg" alt="Slide 2"></div>
    <div class="wf-carousel-item"><img src="slide-3.jpg" alt="Slide 3"></div>
</div>

Data Attributes

Attribute Default Description
data-wf-carousel Required. Marks the wrapper for auto-init on DOMContentLoaded.
data-wf-navigation off Show previous / next arrow buttons.
data-wf-pagination off Show clickable dot indicators below (or beside, in vertical mode) the track.
data-wf-loop off Wrap from the last slide back to the first, and vice versa. Keeps nav buttons always enabled.
data-wf-autoplay off Automatically advance slides. Pauses on hover and focus; resumes on leave.
data-wf-autoplay-interval="ms" 3000 Milliseconds between auto-advances. Minimum enforced: 500.
data-wf-mouse-dragging on Allow click-and-drag scrolling on desktop. Set to "false" to disable.
data-wf-slides-per-page="n" 1 Number of slides visible simultaneously. Slide width is computed automatically.
data-wf-slides-per-page-sm="n" 1 Visible slides on narrow viewports (< 42rem). Overrides data-wf-slides-per-page at that breakpoint.
data-wf-slides-per-move="n" 1 Number of slides to advance per next / previous call.
data-wf-orientation="vertical" horizontal Switches track to column flex, moves buttons to top / bottom, and uses --wf-carousel-slide-height instead of aspect-ratio.
data-wf-disabled off Disable all interaction. Dims the carousel and blocks pointer events.
data-wf-gallery-sync="#selector" CSS selector for an external element containing thumb items. Each thumb needs data-thumb="index" (0-based). The carousel adds .is-active to the matching thumb and clicking any thumb jumps to that slide.

CSS Custom Properties

Property Default Description
--wf-carousel-aspect-ratio 16 / 9 Aspect ratio of each .wf-carousel-item . Set to unset if slides have a fixed height.
--wf-carousel-gap 1rem Gap between slides in the track.
--wf-carousel-scroll-hint 0px Inline padding that peeks the edges of adjacent slides — useful as a "there is more" affordance. Must include a unit (e.g. 2rem ).
--wf-carousel-slide-height 300px Fixed height for slides in vertical orientation. Has no effect in horizontal mode.

Programmatic API & Events

Methods

Access the instance via el._wfCarousel after auto-init, or hold a reference returned by the constructor.

Method Returns Description
goToSlide(index, behavior) void Scroll to a slide by 0-based index. behavior : 'smooth' (default) or 'auto' .
next(behavior) void Advance by slidesPerMove . Wraps if loop is enabled.
previous(behavior) void Retreat by slidesPerMove . Wraps if loop is enabled.
getIndex() number Returns the current 0-based slide index.
getTotal() number Returns the total number of slides.
play() void Start or resume autoplay.
pause() void Pause autoplay until play() is called.
setDisabled(bool) void Enable or disable all interaction. Stops autoplay when true ; restarts it (if configured) when false .
destroy() void Stop autoplay, disconnect the ResizeObserver, and remove all event listeners.

Events

Dispatched on the .wf-carousel wrapper element.

Event Detail Description
wf:slide-change { index, total } Fires whenever the visible slide changes. index is 0-based; total is the full slide count.
JavaScript
import { WojoCarousel } from './src/js/components/wf-carousel.js'

// Manual init
const el = document.querySelector('[data-wf-carousel]')
const carousel = new WojoCarousel(el).init()

// Programmatic control
carousel.goToSlide(2)          // Jump to third slide (smooth)
carousel.next()                // Advance one step
carousel.previous('auto')      // Retreat instantly (no animation)
console.log(carousel.getIndex(), '/', carousel.getTotal())

// Autoplay control
carousel.play()
carousel.pause()

// Via element reference (after auto-init)
const c = document.getElementById('my-carousel')._wfCarousel
c.setDisabled(true)

// Listen for slide changes
el.addEventListener('wf:slide-change', e => {
    console.log(`Slide ${e.detail.index + 1} of ${e.detail.total}`)
})

Class Reference

All modifier classes available on .wf-carousel

Generated DOM structure
<div class="wf-carousel wf-carousel--ready">        <!-- your element -->
    <div class="wf-carousel-stage">               <!-- generated: positions buttons relative to track -->
        <div class="wf-carousel-track">           <!-- generated: scroll-snap flex container -->
            <div class="wf-carousel-item">…</div>
            <div class="wf-carousel-item">…</div>
        </div>
        <button class="wf-carousel-btn wf-carousel-btn--prev">…</button>   <!-- data-wf-navigation -->
        <button class="wf-carousel-btn wf-carousel-btn--next">…</button>
    </div>
    <div class="wf-carousel-pagination">          <!-- data-wf-pagination; outside stage -->
        <button class="wf-carousel-dot is-active"></button>
        <button class="wf-carousel-dot"></button>
    </div>
</div>
Class Type Description
wf-carousel Base Outer wrapper. position:relative container; set CSS custom properties here.
wf-carousel-item Child Each slide. Width is computed from --wf-carousel-slides-per-page . Override aspect ratio via --wf-carousel-aspect-ratio .
wf-carousel-stage Generated Intermediate wrapper created by JS that contains the track and nav buttons. Acts as the position:relative context for the buttons, ensuring they center against the track height only — not the total carousel height (which includes pagination).
wf-carousel-track Generated Scroll-snap flex track created by JS. Wraps all .wf-carousel-item children after init. Sits inside .wf-carousel-stage .
wf-carousel-btn-* Generated Circular nav buttons ( --prev , --next ). Generated when data-wf-navigation is set. Placed inside .wf-carousel-stage so top:50% centres on the track, not the pagination row. Add data-wf-size="sm|lg" to the wrapper for smaller or larger buttons.
wf-carousel-pagination Generated Dot indicator row placed directly on .wf-carousel , outside the stage, so it sits below the track without affecting button centering. In vertical mode it is position:absolute and floats at the inline-end edge instead. Generated when data-wf-pagination is set.
wf-carousel-dot Generated Individual pagination dot. .is-active marks the current slide and expands the dot to 1.25rem wide (or tall in vertical mode).
wf-carousel-counter Optional Absolute-positioned badge for slide position text (e.g., "2 / 5"). Not generated by JS — add it manually when needed.
wf-carousel--vertical State Added when data-wf-orientation="vertical" . Switches track to column flex and repositions nav buttons and pagination dots.
wf-carousel--disabled State Added by setDisabled(true) or data-wf-disabled . Dims the carousel (opacity 0.55) and blocks pointer events.
wf-carousel--ready State Added by JS after the first layout frame. Triggers track fade-in. Raw items are hidden until this class is present to prevent flash of unstyled content.
wf-carousel--mouse-dragging
wf-carousel--dragging
State --mouse-dragging : shows grab cursor when idle. --dragging : switches to grabbing cursor and disables scroll-snap during an active drag.
Show More