Parallax Slider
Depth carousel: while the track slides, each slide's background shifts the other way and moves slower than the title on top of it.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Gallery has 44 effects, including 6 free. Explore the category →
3 usage examples



How it works
Each .pxsl-slide holds two layers: a .pxsl-bg background wider than the slide (160%, overflowing by 30% on each side) and a .pxsl-caption title in front. On change, the track slides by 100% like an ordinary carousel, and the script also shifts each background by 30% of its own width per step of distance from the visible image, in the opposite direction.
The result: the title crosses the frame at full speed while the landscape behind it only covers about half the way. That speed gap creates the sense of relief. The background has its own transition (0.6 s), slightly longer than the track's (0.5 s), which adds to the lag. The value 30 is set with the frame's data-depth attribute.
The parallax only shows if the background has shapes: a flat colour or a near-uniform gradient slides by unnoticed. The demo backgrounds therefore carry a light disc and slanted stripes. With your photos, use an <img class="pxsl-bg"> (cropped with object-fit: cover) or a <div class="pxsl-bg"> with a background-image; a landscape with ridges or a horizon gives the best result.
Controls: ‹ › arrows, ← → keys while focus is in the frame, horizontal drag of more than 50 px (Pointer Events). After the last view, back to the first. Each .pxsl-carousel is independent, nothing is put on window, and running the script again does nothing (data-pxsl-ready).
Accessibility
- Decorative backgrounds: the
.pxsl-bglayer is scenery only; a background<img>takesalt="", and the information goes in the caption or the slide's text. - Roles:
role="region"andaria-roledescription="carousel"on the frame, "slide" groups named "2 of 3", hidden slides set toinert+aria-hidden. - Announcement and controls: invisible
aria-live="polite"area after each change; arrows are real named buttons, white focus ring, ← → keys. - Reduced motion: under
prefers-reduced-motion: reduce, no sliding and no background shift: the view changes at once. The depth goes, navigation stays. - Readability: the white title has a drop shadow; on a light background, add a dark veil under the caption to keep the contrast.
Browser compatibility
About 4 KB of JavaScript. Playwright measurements on 08/11/2026 in Chromium, Firefox and WebKit: two independent carousels, script run twice with no effect, Tab, Enter and →, finger swipe (Chromium, 390 px) and mouse drag, background shift read mid-transition, reduced motion without errors. Minimum versions from @mdn/browser-compat-data 8.1.8; inert sets them.
Without inert, everything works but a link in a hidden view can still be reached by keyboard. Without aspect-ratio (Safari 14), set --pxsl-height. Without JavaScript, the first view shows with its background, with no navigation.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0169-root">
<div class="pxsl-carousel" role="region" aria-roledescription="carousel" aria-label="Slideshow" data-slide="slide" data-of="of">
<div class="pxsl-track">
<div class="pxsl-slide"><div class="pxsl-bg pxsl-bg-1"></div><span class="pxsl-caption">Parallax 1</span></div>
<div class="pxsl-slide"><div class="pxsl-bg pxsl-bg-2"></div><span class="pxsl-caption">Parallax 2</span></div>
<div class="pxsl-slide"><div class="pxsl-bg pxsl-bg-3"></div><span class="pxsl-caption">Parallax 3</span></div>
<!-- one div.pxsl-slide per view; your photo: <img class="pxsl-bg" src="…" alt=""> instead of the background div -->
<!-- depth: data-depth="30" (optional) on .pxsl-carousel -->
</div>
<button type="button" class="pxsl-arrow pxsl-prev" aria-label="Previous slide"><svg>…</svg></button>
<button type="button" class="pxsl-arrow pxsl-next" aria-label="Next slide"><svg>…</svg></button>
</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Depth (HTML — data-depth on .pxsl-carousel) |
30 | Background shift, in % of its width, per slide of distance. 15 for a subtle effect, 40 for strong relief; beyond that, the edge of the background may show. |
Background overflow (CSS — inset and size of .pxsl-bg) |
-30% · 160% | If you raise the depth, enlarge the background accordingly so it always covers the slide. |
Durations (CSS — --pxsl-duration, --pxsl-bg-duration) |
0.5s · 0.6s | A background slower than the track strengthens the sense of depth. |
Size (CSS — --pxsl-width, --pxsl-ratio, --pxsl-height) |
640px · 16 / 10 · auto | Maximum width, format and optional imposed height. |
Arrows and corners (CSS — --pxsl-arrow-bg, --pxsl-radius) |
white at 20% · 1rem | Darken the arrows over light skies. |
Demo backgrounds (CSS — .pxsl-bg-1 to .pxsl-bg-3) |
gradients with disc and stripes | Remove them as soon as you add your images. |
Spoken texts (HTML — data-slide, data-of, aria-label) |
slide · of · Slideshow | "stage 2 of 3", "chapter 1 of 3"… |
FAQ
data-depth to 40, or lengthen --pxsl-bg-duration.