v147 · CSS · Scroll-driven animations · demo
Progress Tracker
A sticky reading-progress bar driven by a named view timeline in CSS — using the new scroll named range to track the full scroll extent of the container, with JavaScript controls exposing parser, computed, and fallback states.
Scroll-driven animations: timeline named ranges
The Scroll-driven Animations API lets you tie CSS animations to the scroll position of a container using a ScrollTimeline or ViewTimeline. A ViewTimeline tracks when its subject element intersects a scroll container.
Named ranges — entry, exit, cover, contain — previously only described portions of the timeline where the subject was visible in the scroll port. This worked well for element-level animations like fade-in-on-scroll, but left a gap: how do you animate something across the full scroll extent of the container?
The scroll named range, new in Chrome 147, solves this. It maps to the entire scrollable range of the underlying scroll container — from 0% to 100% of scrollHeight − clientHeight. Attached to the article element itself as the subject, it gives you a progress bar that spans the whole scroll, not just the article's visibility window.
This is the progress bar you're looking at. It uses view-timeline-name: --article-progress on this article content, then the sticky fill targets that timeline with animation-range: scroll 0% scroll 100%. The fill grows from left to right as you scroll the container, reaching 100% at the very bottom in supporting browsers.
Without the scroll range, you would have had to use a ScrollTimeline on the container element directly — which requires JavaScript to name or reference. The new named range keeps it in pure CSS.
Keep scrolling to see the bar fill completely. The bar resets as you scroll back toward the top. The lab below also shows the measured JavaScript fallback when the browser parses the syntax but cannot drive the CSS timeline yet.
range lab
scroll offset0 px of 0 px
selected declarationanimation-range: scroll 0% scroll 100%
parser resultchecking exact scroll range
computed rangewaiting for layout
Before (cover / contain)
Ranges only cover the portion of the timeline where the subject is visible. Good for element animations, not full-page scroll progress.
After (scroll — Chrome 147)
Maps to the full scroll extent of the container. Perfect for reading-progress bars and viewport-wide effects.
@keyframes progress-fill {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.scroll-article {
timeline-scope: --article-progress;
}
.article-inner {
view-timeline-name: --article-progress;
view-timeline-axis: block;
}
.progress-fill {
transform-origin: left center;
animation: progress-fill linear;
animation-timeline: --article-progress;
/* 'scroll' named range = full container scroll extent (Chrome 147+) */
animation-range: scroll 0% scroll 100%;
}
see also
- Full-Range Fade — cover vs scroll range comparison
- Back to feature index
- ChromeStatus entry
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗