Scroll-triggered animation as the missing piece for scrollytelling on the web

In progressBrecht De Ruytearticle2026-10-13read planted software engineeringprogramming

Synopsis — AI-drafted from Dan's notes

A tutorial essay on utilitybend, Brecht De Ruyte’s blog, published 13 October 2026. The argument is that the web already had scroll-driven animation, where the scroll position scrubs an animation back and forth, and that this is the wrong tool for most storytelling. A headline or a card entering the viewport shouldn’t freeze half-drawn when the reader stops scrolling. What was missing was a native way to let the scroll position start an ordinary timed animation and then let it run. Until now that meant JavaScript, with an IntersectionObserver toggling a class.

The new CSS does it with two properties. timeline-trigger goes on the watched element and names a trigger with a view() source and an activation range (his default is entry 100% exit 0%). animation-trigger then ties an animation to that trigger with an enter action and an exit action: play-forwards, play-backwards, play-once, pause, reset or none. Reversible sections pair forwards with backwards; one-time intros use play-once none. A trick with attr() lets one rule serve every trigger name. Five demos build it up: a masked headline reveal staggered with sibling-index(), cascading feature cards, variable-font letters, a kinetic quote that mixes triggered reveals with a scroll-driven background drift, and a carousel that draws SVG paths as cards slide in sideways, all without JavaScript.

The last third is responsibility. Split-letter headings need an aria-label on the heading and aria-hidden on the spans; prefers-reduced-motion should switch the triggers off; and because support is Chromium-only so far, everything sits behind @supports (animation-trigger: none) with the content visible by default, so a browser without the feature just shows the page.

Connections