Liking cljdoc? Tell your friends :D

x-scroll-parallax

A parallax scrolling container where slotted children move at different speeds relative to page scroll, creating a depth effect. Each child declares its own parallax factor via data-speed.


Tag

<x-scroll-parallax></x-scroll-parallax>

Attributes

AttributeTypeDefaultDescription
directionenum"vertical"Scroll axis: vertical horizontal
sourceenum"document"Scroll source: document (page scroll)
easingenum"none"Smoothing: none (direct) smooth (CSS transition)
disabledbooleanfalseFreeze all parallax transforms
labelstring""Accessible label for the parallax region

Data Attributes (on children)

AttributeTypeDefaultDescription
data-speednumber1Speed factor: 0=fixed, 1=normal, <1=slower, >1=faster, negative=reverse
data-offsetnumber0Initial pixel offset added to parallax transform
data-opacitystring""Set to "fade" for viewport enter/leave opacity fade
data-scalestring""Set to "grow" for 0.85→1 scale effect

Properties

PropertyTypeReflects attributeNotes
directionstringdirection
sourcestringsource
easingstringeasing
disabledbooleandisabled
labelstringlabel
progressnumberRead-only. Current scroll progress [0, 1].

Events

EventBubblesComposedDetailDescription
x-scroll-parallax-enteryesyes{ progress }Component enters the viewport
x-scroll-parallax-leaveyesyes{ progress }Component leaves the viewport
x-scroll-parallax-progressyesyes{ progress }Fires each frame while visible (rAF cadence)

Slots

SlotDescription
(default)Child elements to parallax. Each can have data-speed, data-offset, data-opacity, data-scale.

CSS Custom Properties

PropertyDefaultDescription
--x-scroll-parallax-perspectivenoneCSS perspective on viewport (e.g. 1000px)
--x-scroll-parallax-overflowhiddenViewport overflow (visible to allow overflow)
--x-scroll-parallax-smooth-duration80msTransition duration when easing="smooth"
--x-scroll-parallax-fade-range20%Viewport fraction for opacity fade transition
--x-scroll-parallax-scale-min0.85Minimum scale for data-scale="grow"
--x-scroll-parallax-disabled-opacity0.55Opacity when disabled

Customising via CSS custom properties

<x-scroll-parallax
  style="--x-scroll-parallax-perspective: 1000px;
         --x-scroll-parallax-fade-range: 30%;
         --x-scroll-parallax-scale-min: 0.9;">
  <div data-speed="0.5" data-opacity="fade" data-scale="grow">Content</div>
</x-scroll-parallax>

Accessibility

  • Viewport has role="region" with aria-label from the label attribute.
  • ARIA live region announces enter/leave for screen readers.
  • Reduced motion: When prefers-reduced-motion: reduce is active, all transforms, fades, and scales are disabled via CSS. The scroll handler is suppressed, so progress events do not fire. enter and leave events (from IntersectionObserver) still fire.
  • The component is not focusable (no keyboard interaction needed).

Usage

Basic parallax layers

<x-scroll-parallax label="Hero">
  <div data-speed="0.3" class="background">Background</div>
  <div data-speed="0.7" class="midground">Midground</div>
  <div data-speed="1.2" class="foreground">Foreground</div>
</x-scroll-parallax>

With fade and scale effects

<x-scroll-parallax easing="smooth">
  <img data-speed="0.5" data-opacity="fade" src="bg.jpg" />
  <h1 data-speed="0.8" data-scale="grow">Welcome</h1>
</x-scroll-parallax>

Horizontal parallax

<x-scroll-parallax direction="horizontal">
  <div data-speed="0.5">Slow layer</div>
  <div data-speed="1.5">Fast layer</div>
</x-scroll-parallax>

How it works

  1. An IntersectionObserver activates the component when it enters the viewport. Off-screen components have zero cost.
  2. A scroll listener on window triggers a single requestAnimationFrame per frame.
  3. Each frame, the component reads its position via getBoundingClientRect(), computes a progress value [0, 1], and applies CSS transforms to each slotted child based on their data-speed factor.
  4. The transform formula centers the parallax so children are at their natural position when the component is centered in the viewport:
    offset = (progress - 0.5) * viewport_size * (speed - 1) + data-offset
    

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close