The Old Way
JavaScript scroll listeners on the main thread caused jank. Forced layout reflows, complex timing logic, and third-party libraries were required for even basic scroll effects.
◆ Zone 1
Drive animations with your scroll position.
Pure CSS, zero JavaScript.
For years, scroll animations required JavaScript libraries. CSS Scroll-Driven Animations changed everything — now your scroll position is a first-class animation input, handled entirely by the browser.
JavaScript scroll listeners on the main thread caused jank. Forced layout reflows, complex timing logic, and third-party libraries were required for even basic scroll effects.
CSS Scroll-Driven Animations run off the main thread, are composited by the GPU, and declared entirely in CSS. No JavaScript, no performance overhead, no library dependency.
scroll() TimelineLinks animation progress to a scroll container from 0% (top) to 100% (bottom). The progress bar at the top of this page is powered by this technique.
.progress-bar {
animation: grow-bar linear both;
animation-timeline: scroll();
animation-range: 0% 100%;
}
@keyframes grow-bar {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
/* Or target a specific scroll container */
animation-timeline: scroll(root block);
view() TimelineLinks animation progress to an element’s visibility in a scroll container.
.card {
animation: fade-up linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(60px); }
to { opacity: 1; transform: translateY(0); }
}
Fine-tune exactly when the animation runs using named range values:
/* entry: element entering the scroll port */ animation-range: entry 0% entry 100%; /* contain: element is fully visible */ animation-range: contain 0% contain 100%; /* exit: element leaving the scroll port */ animation-range: exit 0% exit 100%; /* cover: first pixel enters to last pixel exits */ animation-range: cover 0% cover 100%; /* Mix and match any two range values */ animation-range: entry 20% exit 80%;
Browser Support
Select a timeline type and preset, adjust the range sliders, and watch the generated CSS update in real time.
scroll() ties to the page scroll position.
view() ties to how visible the element is.