Scroll-driven animations (2024+)
Animations tied to scroll position β no JS needed
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-on-scroll {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% entry 80%;
}The browser ties the animation's progress to where the element is in the viewport. Element enters β animation runs proportionally.
Two new properties
- `animation-timeline` β what's "time" for this animation?
* view() β element entering the viewport.
* scroll() β the document scroll position.
- `animation-range` β what portion of the timeline to use.
* entry 0% entry 100% β full entry (element appears at bottom edge, finishes when fully in view).
* cover 0% cover 100% β entire scroll-through.
The progress-bar pattern
.progress {
position: fixed; top: 0; left: 0;
height: 4px;
width: 100%;
transform-origin: left;
background: #3B82F6;
animation: shrink linear;
animation-timeline: scroll(root);
}
@keyframes shrink {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}A bar that fills as you scroll the page. Zero JS.
Browser support (2026)
Chrome / Edge / Safari 17.4+ all support it. Firefox is behind but progressing. Treat as a progressive enhancement.
reduced-motion still wins
Same media query rules apply β kill scroll-driven animations for opted-out users.
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 10 lessons in each track are free. No card needed for those.