Scroll-Driven Animations in CSS

From the CSS cheat sheet · Modern CSS Features · verified Jul 2026

Scroll-Driven Animations

Drive @keyframes from scroll position or element visibility — no JS required.

css
/* Animate as the page scrolls (root scroller) */
@keyframes progress {
  to { width: 100%; }
}
.progress-bar {
  animation: progress linear;
  animation-timeline: scroll();    /* drive from page scroll */
}

/* Animate based on element entering the viewport */
@keyframes fade-in {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
.card {
  animation: fade-in linear both;
  animation-timeline: view();      /* drive from element's own view progress */
  animation-range: entry 0% cover 30%;
}
💡 animation-timeline: scroll() drives from a scroller; view() drives from element visibility
⚡ animation-range controls WHEN in the timeline the animation plays (entry / cover / exit)
⚠️ Firefox still needs a flag (as of 2026); use @supports (animation-timeline: scroll()) as a fallback
🔥 Always pair with @media (prefers-reduced-motion: reduce)

More CSS tasks

Back to the full CSS cheat sheet