CSS Scroll-driven Animation Generator
What a scroll-driven animation is
Scroll-driven animations tie an animation's progress to a scroll position instead of to time. A reading-progress bar, a parallax layer or a reveal-on-enter effect becomes a few lines of CSS, running off the main thread with no scroll listener in sight.
Syntax
animation: <name> linear; animation-timeline: scroll(); | view();
| Part | What it controls |
|---|---|
| scroll() | Progress follows a scroll container from its start to its end. Ideal for reading-progress indicators. |
| view() | Progress follows one element's journey through the viewport, which is what drives reveal and parallax effects. |
| animation-range | Narrows where the animation runs, such as entry 0% cover 50%, so a reveal finishes before the element is fully on screen. |
| animation-timeline | Replaces the time-based clock. The animation's duration is then ignored entirely. |
| linear easing | Scroll-linked animations should use linear easing — the scroll itself provides the pacing, and any other curve fights it. |
| timeline-scope | Lets an animation reference a timeline defined on an element that is not an ancestor. |
Notes from practice
Duration becomes meaningless
Once animation-timeline is set, animation-duration no longer applies. Scroll distance is the clock, so leaving a duration in the shorthand is harmless but misleading.
It runs off the main thread
Unlike a scroll event listener, this is handled by the compositor, so it stays smooth while JavaScript is busy. That is the real reason to prefer it.
Always provide a static fallback
In browsers without support the animation simply never runs, so the element stays at its initial keyframe. Make that initial state the usable one — opacity: 0 as a starting point will hide your content entirely.
CSS Scroll-driven Animation Generator FAQ
How do I create a scroll progress bar with CSS only?
Animate a bar's scaleX from 0 to 1 and set animation-timeline: scroll(). The bar then fills in step with the page's scroll position, with no JavaScript and no scroll listener.
What is the difference between scroll() and view()?
scroll() tracks a scroll container's own progress from top to bottom, which suits a page progress indicator. view() tracks a single element's progress through the viewport, which is what you want for reveal, parallax and sticky-image effects.
Do scroll-driven animations need JavaScript?
No. animation-timeline is pure CSS and runs on the compositor, so it stays smooth even when the main thread is busy — a notable advantage over a scroll event listener.
Which browsers support animation-timeline?
Chrome and Edge support it; Firefox and Safari are behind. Treat it as progressive enhancement and make sure the un-animated state is the usable one, because unsupported browsers will simply hold the first keyframe.
How do I control when a scroll animation starts and ends?
Use animation-range, for example animation-range: entry 0% cover 40%, which runs the animation from the moment the element enters the viewport until it is 40% covered. Without it the animation spans the element's entire journey.
Related generators
- Keyframe Animation — Pick a ready-made @keyframes set and tune timing, repeat, direction and fill mode.
- Transition — Tune duration, delay and easing, including cubic-bezier curves and spring or bounce easing with linear().
- Motion Path — Move an element along an SVG path with offset-path and animate offset-distance.
- Scroll Snap — Make carousels and galleries lock to each slide. Swipe or scroll the preview to feel it.
Part of CSSGen.dev — 30 free visual CSS generators with browser support built in.