Scroll-driven animations
Animations driven by scrolling, with no event listeners and off the main thread.
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.
Eight parts of a building, one after another.
- 01Foundations
- 02Pillars
- 03Floors
- 04Façades
- 05Roof
- 06Towers
- 07Weather vanes
- 08Moat
End of the tour.
Browser support
Limited availability| Feature | Desktop | Mobile | |||||
|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Safari | Chrome Android | Firefox Android | Safari iOS | |
| animation-timeline (scroll(), view()) | 115Chrome: 115 | 115Edge: 115 | ✓previewFirefox: preview | 26Safari: 26 | 115Chrome: 115 | —Firefox: No | 26Safari: 26 |
| animation-range | 115Chrome: 115 | 115Edge: 115 | ✓previewFirefox: preview | 26Safari: 26 | 115Chrome: 115 | —Firefox: No | 26Safari: 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><!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
Keep in mind
- The animation shorthand resets animation-timeline: declare the timeline after it.
- Wrap them in @supports (animation-timeline: view()) and prefers-reduced-motion: no-preference.
- The best-known polyfill (scroll-timeline-polyfill) has not been updated since 2024.
Further reading
Sources
- Bugzilla 1676779 (Firefox: planes de activación)accessed 1 Oct 2026
- MDN · Experimental features in Firefoxaccessed 1 Oct 2026
- MDN · Scroll-driven animations22 Sep 2026
- Interop 202612 Feb 2026