02 · Scroll-driven

Scroll-driven

Progress bar and reveals on viewport entry

Chrome 115+
← Index
scroll() → progress

Instead of animating over time, you map the document scroll progress to an animation. Scrolling up rewinds it.

animation-timeline: scroll(root block)

view() → per element

Each card has its own timeline as it crosses the viewport. No IntersectionObserver.

animation-timeline: view(); animation-range: entry 0% cover 28%

No listeners

Before: scroll listener + manual calculation + width update. Now: two CSS properties.

More use cases

Parallax, shrinking headers, timelines — all with the same API.

range: entry / exit

animation-range: entry 0% cover 28% defines at which point of viewport entry the animation starts and covers.

cover vs contain

cover animates while the element crosses the entire viewport; contain only while fully visible.

Named timeline

With timeline-scope you can control an element's animation from an ancestor container.

Performance

The browser runs the animation on the compositor — no layout thrashing, no jank.

css
/* barra de progreso — mapea el scroll del documento */
.page-progress {
  animation: grow linear both;
  animation-timeline: scroll(root block);
}
@keyframes grow { to { transform: scaleX(1); } }

/* cada card se anima al entrar al viewport */
.view-card {
  animation: reveal linear both;
  animation-timeline: view();
  animation-range: entry 0% cover 28%;
}
@keyframes reveal {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

An honest note on support

Many of these APIs are recent and not yet in every browser (see the pill on each section). The nice part is they all degrade gracefully: the carousel still scrolls, the accordion opens/closes, the textarea works — just without the animated "plus".