Web APIs, todayLab · Alex Harto

Scroll-driven animations

Animations driven by scrolling, with no event listeners and off the main thread.

In your browser: checking…Reviewed 1 Oct 2026

animation-timeline: scroll() ties an animation to a container’s scroll position, and view() to an element’s progress through the viewport; animation-range sets the span. They are regular CSS animations: the compositor runs them and they do not block the page.

They have been in Chrome since 115 and in Safari since 26. Firefox only enables them in Nightly, and Mozilla has announced it plans to ship them in October or early November 2026. They are part of Interop 2026.

What it is for

  • Reading progress bars
  • Elements revealed as they enter the screen
  • Parallax and shrinking headers

Demo

Scroll inside the box. The bar, the percentage, the header and the cards are all driven by scrolling; there is not a single line of JavaScript.

Tour

Eight parts of a building, one after another.

  1. 01Foundations
  2. 02Pillars
  3. 03Floors
  4. 04Façades
  5. 05Roof
  6. 06Towers
  7. 07Weather vanes
  8. 08Moat

End of the tour.

Browser support

Limited availability
FeatureDesktopMobile
ChromeEdgeFirefoxSafariChrome AndroidFirefox AndroidSafari iOS
animation-timeline (scroll(), view())115Chrome: 115 115Edge: 115 ✓previewFirefox: preview26Safari: 26 115Chrome: 115 —Firefox: No26Safari: 26
animation-range115Chrome: 115 115Edge: 115 ✓previewFirefox: preview26Safari: 26 115Chrome: 115 —Firefox: No26Safari: 26

Compatibility generated on every deploy from MDN browser-compat-data 8.1.3 (24 Sep 2026) · web-features 3.40.0 · checked by hand: 1 Oct 2026

Minimal code

<!doctype html>
<meta charset="utf-8">
<title>Scroll-driven animations · ejemplo mínimo</title>
<style>
  body { font: 18px/1.6 system-ui; max-width: 40rem; margin: auto; padding: 2rem; }
  section { margin: 60vh 0; padding: 2rem; background: #eee; }
  #progress { position: fixed; inset: 0 0 auto; height: 4px; background: #c0643a; transform-origin: left; }

  @keyframes grow { from { scale: 0 1; } }
  @keyframes reveal { from { opacity: 0; translate: 0 2rem; } }

  /* Solo si el navegador lo soporta y la persona no ha pedido menos movimiento */
  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      /* La barra avanza con el scroll de la página */
      #progress { animation: grow linear both; animation-timeline: scroll(root block); }
      /* Cada sección aparece al entrar en pantalla (el shorthand va antes que el timeline) */
      section { animation: reveal linear both; animation-timeline: view(); animation-range: entry 0% cover 40%; }
    }
  }
</style>
<div id="progress"></div>
<h1>Desplázate hacia abajo</h1>
<section>Uno</section>
<section>Dos</section>
<section>Tres</section>

What’s new

  1. Firefox 157 (in Nightly) mirrors startTime when playbackRate flips sign on these animations.
  2. Chrome 146: scroll-triggered animations (animation-trigger).
  3. They join Interop 2026.
  4. Safari 26 ships them.

Keep in mind

  1. The animation shorthand resets animation-timeline: declare the timeline after it.
  2. Wrap them in @supports (animation-timeline: view()) and prefers-reduced-motion: no-preference.
  3. The best-known polyfill (scroll-timeline-polyfill) has not been updated since 2024.

Further reading

Sources