CSS Animations · Scroll

Scroll owns the timeline.

Everything on this page reads real scroll position, not a fixed timer. Some effects use data-kui-timeline — a native CSS view()/scroll() timeline that reverses the instant you scroll back up. Others need real measurement — pinning, scrollytelling, horizontal tracks — so they run through the library's shared JS orchestrator instead.

The bar above the header and the ring in the lower-left corner are both live — watch them as you scroll this page.

Volcán de Fuego erupting at night, glowing lava fountains arcing over the silhouetted cone under a dense, star-filled sky

Scroll reveal & parallax

Catalog section B — 12 named effects. Nine are live below; three (reveal-repeat, scroll-skew, reveal-direction-aware) are documented in the catalog but not yet wired into the shipped library — reveal-repeat was removed as byte-identical to reveal-once once the activation binder stopped re-observing after first entry, and the other two have no registered primitive to grep for. parallax-* and scroll-* use data-kui-timeline, not data-kui-on — progress-linked, so they reverse on scroll-up by design.

Reveal & fade — 2

A calm alpine lake with a mirror-still reflection of the mountains above it
data-kui="reveal-once"
Rolling desert sand dunes with strong shadow texture
data-kui="scroll-fade timeline:view"

Parallax — 5

Each frame clips a deliberately oversized image so the transform never reveals a bare edge — the amount and direction of oversize differs per effect (see the CSS comments in this page's <style> block).

A sweeping alpine mountain range under dramatic light
parallax-y — distance:120px
A long panoramic coastline with steep cliffs meeting the ocean
parallax-x — distance:100px
A tall waterfall cascading through a narrow canyon
parallax-scale — scale:1.25
The aurora borealis glowing green over a mountain landscape
parallax-rotate — angle:10deg
A misty mountain valley with layered ridgelines fading into fog
depth-layer — distance:200px (same primitive as parallax-y, more travel)

Scroll mechanics

Catalog section C — 11 named effects, all backed by real primitives. Ten are demonstrated below; video-scrub is verified in kuinetic.js (the same media-scrub primitive as sequence-scrub, just fed a <video> instead of a frame pattern) but is left unwired here — this pass sourced photography, not video footage, and wiring a real <video> element in in place of a frame sequence is a small, well-understood follow-up. Everything here needs the shared JS orchestrator: measurement, resize invalidation, cleanup.

Pinning — 4

pin-section — the default carries an auto-inserted spacer, so a pin longer than its containing block still reserves scroll room.

An epic, vast canyon vista stretching to the horizon

data-kui="pin-section distance:200vh"

Pinned while the section passes.

pin-until — spacer:false. No spacer is inserted; the sticky panel relies on its own naturally taller sibling for scroll room, the classic sticky-sidebar pattern.

A deep turquoise alpine lake ringed by mountains
Green terraced rice fields carved into a hillside
A tropical island with palm trees and a white sand beach

pin-spacer — same primitive as pin-section, spelled out explicitly: the dashed box below the photo is the real <div data-kui-spacer> the primitive inserts into the DOM.

A narrow slot canyon with warm glowing sandstone walls and light beams
data-kui="pin-spacer distance:120vh"

stacking-cards — the pin primitive applied per card, each at its own offset, so the stack builds up naturally as you scroll.

A single dramatic snow-capped mountain peak against a clear sky
offset:1rem
Tall old-growth redwood trees with sunbeams through the canopy
offset:2.25rem
Sahara desert dune ridgelines lit in warm sunset tones
offset:3.5rem
A turquoise coastline with cliffs meeting bright blue-green water
offset:4.75rem

Scrollytelling — 1

A glacier landscape of blue-white ice under a cold sky

One — the compiler reads the attribute.

Two — parameters are validated before they reach CSS.

Three — channels decide whether effects may compose.

Four — the browser owns the frame loop.

The primitive writes data-kui-step onto the section itself; the highlight above is a plain attribute selector.

Horizontal travel — 1

A sweeping alpine mountain range under dramatic light
Alps
A long panoramic coastline with steep cliffs meeting the ocean
Amalfi coast
A tall waterfall cascading through a narrow canyon
Canyon falls
The aurora borealis glowing green over a mountain landscape
Aurora
A city skyline at dusk with lights on across a wide urban panorama
City nights

data-kui="horizontal-scroll distance:250vh" — a JS orchestrator translates the track directly; nothing here is a native scroll container.

Media scrub — 1 of 2

sequence-scrub's frames:/src: params swap in one real still per fifth of the scroll range via a {i} placeholder in the src pattern — five distinct photos below, not a filter effect. src is a JS-only text param, so the value never reaches a stylesheet — it goes straight to <img>.src — which is why the shared CSS-escape guard on data-kui values leaves braces alone for this one param. The grayscale→color wipe is layered on top from the same real --kui-progress the primitive publishes, so both mechanisms are visible scrolling through this one element.

A sequence of five landscape photos swapping in frame by frame as you scroll, fading from grayscale to full color

data-kui="sequence-scrub frames:5 src:./assets/scenic_scrub_{i}.jpg distance:220vh"

Navigation — 1

scroll-spy writes data-kui-active onto the tracked section and mirrors it onto whatever target selector you point at — here, the matching nav link.

A sweeping alpine mountain range under dramatic light

Region

Mountains

A long panoramic coastline with steep cliffs meeting the ocean

Region

Coasts

Rolling desert sand dunes with strong shadow texture

Region

Deserts

Tall old-growth redwood trees with sunbeams through the canopy

Region

Forests

Native CSS passthroughs — 2

scroll-snap-x / scroll-snap-y just set scroll-snap-type/-align — these are real independently-scrollable containers, not JS-driven like the horizontal track above. Drag or scroll them directly.

A tropical island with palm trees and a white sand beach
scroll-snap-x
A deep turquoise alpine lake ringed by mountains
scroll-snap-x
A narrow slot canyon with warm glowing sandstone walls and light beams
scroll-snap-x
A single dramatic snow-capped mountain peak against a clear sky
scroll-snap-x
A glacier landscape of blue-white ice under a cold sky
scroll-snap-x
An epic, vast canyon vista stretching to the horizon
scroll-snap-y — 1 of 4
The aurora borealis glowing green over a mountain landscape
scroll-snap-y — 2 of 4
A turquoise coastline with cliffs meeting bright blue-green water
scroll-snap-y — 3 of 4
A city skyline at dusk with lights on across a wide urban panorama
scroll-snap-y — 4 of 4