motion-scene
Scroll-driven animation timeline. Pin a stage while scroll progress drives children through keyframes. It's purely declarative, using data attributes.
Live showcase → Declare · Sequence · ComposeHow it works
Wrap a scene in a tall container. The inner stage sticks while the user scrolls. Children with data-from/data-to are scrubbed from their start keyframe to their end keyframe as scroll advances through data-start–data-end (0–1 progress values).
Preview
Scroll inside the box to drive the animation.
Import
CSS variable
The scene exposes --progress (0–1) so you can drive your own CSS effects off scroll position.
Custom scroll container
By default the scene tracks document scroll. Pass a CSS selector via container to use an overflow element instead.
Without pinning
pin defaults to true and, like any HTML boolean attribute, cannot be
switched off from markup: both omitting it and writing pin="false" leave it
true. Set the property to get scrubbed children without a sticky stage.
Properties
| Attribute | Property | Type | Default | Description |
|---|---|---|---|---|
| | | string | '200vh' | Height of the scroll container: controls how much scroll the scene consumes. |
| | | boolean | true | The inner stage sticks to the viewport while scrolling. Cannot be switched off from markup; set el.pin = false |
| | | string | '' | CSS selector for a custom scroll container. Defaults to document scroll when empty. |
Child data attributes
| Property | Type | Default | Description |
|---|---|---|---|
| | JSON | — | Starting keyframe, e.g. {"opacity":0,"y":"-20px"}. Supports x, y, scale, rotate, and any CSS property. |
| | JSON | — | Ending keyframe, same shape as data-from. |
| | number | 0 | Scene progress (0–1) at which this child's animation begins. |
| | number | 1 | Scene progress (0–1) at which this child's animation ends. |
JavaScript API
Control the scene programmatically with play(), pause(), finish(), and cancel(). Pause unbinds the scroll listener so the card freezes mid-scrub. Finish snaps to the end keyframe. Cancel resets to the start. Scroll the box while running to drive the card.
Accessibility
Respects prefers-reduced-motion: when enabled, all scroll-driven animations are disabled and children render at their end state immediately.