Slider

A native horizontal scroller with CSS scroll-snap - swipe, trackpad and keyboard work without any script. varz-slider.js (3.8 kB minified + gzipped) adds arrows, dots, mouse drag, autoplay with a pause button, loop and accessible labels.

One slide, autoplay, loop

Mountains at dawn
Mountains at dawn
Ocean coast
Ocean coast
Forest trail
Forest trail
Desert dunes
Desert dunes

Several slides in view

  • City lights

    Night walk through the old town.

  • Sunset

    The last light over the bay.

  • Meadow

    Wild flowers in early summer.

  • Glacier

    Blue ice at the end of the valley.

  • Mountains

    Two days on the ridge.

  • Ocean

    Surf school week.

Slides out of view are dimmed with --o:.55;--vz-o:1 - the script adds .vz to the slides in view.

Control looks

Generated controls (data-vz-controls) in six dot looks and four arrow looks - bar puts the arrows next to the dots.

Photo 3Photo 4Photo 5Photo 6
data-vz-dots="pill" data-vz-arrows="round"
Photo 3Photo 4Photo 5Photo 6
data-vz-dots="round" data-vz-arrows="square"
Photo 3Photo 4Photo 5Photo 6
data-vz-dots="square" data-vz-arrows="outline"
Photo 3Photo 4Photo 5Photo 6
data-vz-dots="line" data-vz-arrows="plain"
Photo 3Photo 4Photo 5Photo 6
data-vz-dots="ring" data-vz-arrows="round bar"
Photo 3Photo 4Photo 5Photo 6
data-vz-dots="number" data-vz-arrows="outline bar"

CSS only (no script)

The same track without data-varz-slider: swipe, trackpad or Shift + mouse wheel; visible scrollbar.

Forest trail Desert dunes City lights Sunset

Markup

<div data-varz-slider data-vz-autoplay="5000" data-vz-loop aria-label="Featured">
  <div data-varz-track style="--d:flex;--ox:auto;--sst:x mandatory;--sbw:none;">
    <div style="--flb:100%;--fls:0;--ssa:start;">Slide 1</div>
    <div style="--flb:100%;--fls:0;--ssa:start;">Slide 2</div>
  </div>
  <button type="button" data-varz-prev>&lsaquo;</button>
  <button type="button" data-varz-next>&rsaquo;</button>
  <div data-varz-dots>
    <button type="button" data-varz-dot hidden style="--bgc:gray;--vz-bgc:red;"></button>
  </div>
  <button type="button" data-varz-play hidden>...</button>
</div>
<script src="varz.js" defer></script>
<script src="varz-slider.js" defer></script>
AttributeOnWhat it does
data-varz-sliderwrapperTurns the block into a carousel (role region, aria-roledescription carousel).
data-vz-autoplay="ms"wrapperNext slide every ms. Pauses on hover, focus and in hidden tabs; stops for good after a swipe or the pause button. Off with prefers-reduced-motion.
data-vz-loopwrapperArrows wrap around at the ends (autoplay always does).
data-vz-controls="arrows,dots,play"wrapperAdds the controls the markup does not have, with default looks (varz.slider.styles) - a bare track becomes a full slider.
data-vz-dots="pill"wrapperLook of generated dots: pill (default, the active one wider), round, square, line, ring, number.
data-vz-arrows="round"wrapperLook of generated arrows: round (default), square, outline, plain; add bar to place them next to the dots.
data-varz-dot-numberinside the dot templateGets the dot's number (numbered dots in your own markup).
data-varz-trackscrollerThe scroll-snap container; its children are the slides (labelled "1 of 4"). Focusable: ← → keys.
data-varz-prev / data-varz-nextbuttonPrevious / next position, disabled at the ends without loop.
data-varz-dots + data-varz-dotcontainer + templateOne dot per reachable position (fewer than slides when several are in view). Active dot: .vz, aria-current.
data-varz-playbuttonPause / play; shown only with autoplay; .vz while playing.

.vz is added to the slides in view (style with --vz-*), events: varz-slide on the wrapper, varz-activated / varz-deactivated on slides. Scroll props from VARZ: --sst scroll-snap-type, --ssa scroll-snap-align, --sbw scrollbar-width (responsive), --osb overscroll-behavior, --lst list-style, --foc-olo focus outline offset.