Liking cljdoc? Tell your friends :D

<x-scroll-stack>

A scroll-driven card stacking component. Child elements are displayed vertically; as the user scrolls through the component, they animate upward and stack on top of each other like a card deck. Each stacked card is slightly rotated and offset for a "messy pile" look. Scrolling back reverses the animation smoothly.

How it works

The component makes itself tall enough to create scroll room (viewport height + children count x scroll-distance). A sticky inner container keeps the cards visible while the user scrolls. Scroll progress drives per-card transforms (translate + rotate) applied directly to slotted children.

Tag name

x-scroll-stack

Attributes

AttributeTypeDefaultDescription
peeknumber6Pixels of each stacked card that remain visible
rotationnumber3Maximum rotation in degrees for stacked cards
scroll-distancenumber150Pixels of scroll needed to stack one card
alignstring"center"Vertical position of the stack: "top", "center", "bottom"
disabledbooleanfalseWhen present, disables scroll-driven animation

Properties

PropertyTypeRead-onlyDescription
peeknumberNoReflects peek attribute
rotationnumberNoReflects rotation attribute
scrollDistancenumberNoReflects scroll-distance attribute
alignstringNoReflects align attribute
disabledbooleanNoReflects disabled attribute
stackedCountnumberYesNumber of fully stacked cards
progressnumberYesOverall stacking progress (0.0 to 1.0)

Methods

MethodDescription
refresh()Re-caches child dimensions and recalculates layout. Call after dynamically changing child sizes.

Events

EventDetailDescription
x-scroll-stack-change{ stackedCount, totalCount, progress }Fired when the number of stacked cards changes
x-scroll-stack-progress{ progress, stackedCount, totalCount }Fired on scroll with current progress

Slots

SlotDescription
(default)Child elements to be stacked. Any element works; cards, images, divs, etc.

CSS Custom Properties

PropertyDefaultDescription
--x-scroll-stack-peek6pxPeek offset between stacked cards
--x-scroll-stack-rotation3degMaximum rotation
--x-scroll-stack-gap1remGap between cards in their unstacked state
--x-scroll-stack-padding-top2remTop padding inside the sticky container

CSS Parts

PartDescription
containerThe sticky inner container

Accessibility

  • The container has role="region".
  • When prefers-reduced-motion: reduce is active, all transitions are disabled. Cards still stack/unstack based on scroll position, but without animated transitions.

Usage

<x-scroll-stack peek="8" rotation="4" scroll-distance="200" align="center">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
  <div class="card">Card 4</div>
</x-scroll-stack>

Listening to events

const stack = document.querySelector('x-scroll-stack');
stack.addEventListener('x-scroll-stack-change', (e) => {
  console.log('Stacked:', e.detail.stackedCount, '/', e.detail.totalCount);
});

Dynamic refresh

// After changing child sizes
stack.refresh();

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