Scroll-Driven Animations Overview
- CSS Basics
- Selectors & Specificity
- Box Model & Units
- Typography & Text Styling
- Colors & Color Spaces
- Positioning & Stacking Context
- Flexbox
- Grid
- Grid Advanced
- Responsive Design
- Container Queries
- Pseudo-classes & Pseudo-elements
- Modern Selectors
- CSS Custom Properties
- CSS Functions
- Transitions & Animations
- Transforms
- Forms & Input Styling
- CSS Architecture & Methodologies
- Accessibility in CSS
- Performance & Optimization
- View Transitions & Modern APIs
- Cascade Layers & Scope
What Scroll-Driven Animations Are
Traditionally, animating something in sync with scroll position required JavaScript, listening to scroll events and manually updating styles. Scroll-driven animations let the browser tie a @keyframes animation directly to scroll progress, natively in CSS.
Linking an Animation to Scroll with animation-timeline
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.reveal {
animation: fade-in linear both;
animation-timeline: view();
}animation-timeline: view() ties the animation's progress to how far the element has scrolled into (and through) the viewport, instead of tying it to a fixed time duration.
A Practical Example: A Reading Progress Bar
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.progress-bar {
transform-origin: left;
animation: grow-progress linear;
animation-timeline: scroll();
}animation-timeline: scroll() ties progress to the scroll position of the whole page (or a scrollable container), a common pattern for a top-of-page reading progress indicator.
Why This Matters
Because the browser itself drives the animation instead of JavaScript reacting to scroll events, these animations tend to run more smoothly, since they are not competing with the main thread for every scroll event fired.
A Note on Support
Scroll-driven animations are a newer addition to CSS and are not yet supported everywhere. For a project that must support older browsers, a JavaScript-based fallback (such as the Intersection Observer API) may still be necessary alongside this native approach.