π What Is @scroll-timeline?
The @scroll-timeline at-rule is part of the newScroll-Linked Animations API. It allows animations to progress based on scroll position instead of time! π
This enables smooth effects like parallax, progress indicators, reveal animations, and synchronized scrolling animations β all with pure CSS.
π§© Basic Syntax
Basic @scroll-timeline syntax
@scroll-timeline myTimeline {
source: auto;
orientation: block;
scroll-offsets: 0%, 100%;
}β You create a named timeline (e.g., myTimeline)
β Then attach it to animations using animation-timeline.
π― Core Properties of @scroll-timeline
| Property | Description |
|---|---|
| source | The scroll container (default: viewport) |
| orientation | block (vertical) or inline (horizontal) |
| scroll-offsets | Defines animation progress points during scroll |
π§ͺ Example: Fade in Element on Scroll
1οΈβ£ Define the Scroll Timeline
@scroll-timeline
@scroll-timeline fadeTimeline {
source: auto;
orientation: block;
scroll-offsets: 0%, 100%;
}2οΈβ£ Define Keyframes
@keyframes
@keyframes fadeIn {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}3οΈβ£ Apply Timeline to Animation
Connect animation to scroll
.item {
animation-name: fadeIn;
animation-duration: 1s; /* becomes irrelevant */
animation-timeline: fadeTimeline;
animation-range: 0% 100%;
}β The animation now progresses as the user scrolls.
β No JavaScript needed.
π¬ Example: Horizontal Scroll Timeline
Horizontal scroll timeline
@scroll-timeline horizontalTimeline {
source: auto;
orientation: inline;
scroll-offsets: 0px, 500px;
}β Useful for horizontal carousels, galleries, or image comparisons.
π Example: Progress Bar That Fills During Scroll
Progress bar scroll animation
@scroll-timeline progressTimeline {
source: auto;
orientation: block;
scroll-offsets: 0%, 100%;
}
.progress-bar {
animation: fillBar 1s linear;
animation-timeline: progressTimeline;
animation-range: 0% 100%;
}
@keyframes fillBar {
from { width: 0%; }
to { width: 100%; }
}β The progress bar fills exactly as the user scrolls down the page.
π¦ Example: Parallax Scroll Effect
Parallax animation
@keyframes parallaxShift {
from { transform: translateY(0); }
to { transform: translateY(-200px); }
}
@scroll-timeline parallaxTimeline {
scroll-offsets: 0%, 100%;
}
.bg-layer {
animation: parallaxShift 1s linear;
animation-timeline: parallaxTimeline;
}β Creates cinematic parallax movement based on scroll.
π§ animation-range (Important!)
To control how much of the scroll should drive the animation:
animation-range
animation-range: entry 0% exit 100%;- entry β When element first enters viewport
- exit β When element leaves
π Full Working Example
Full Scroll Animation
@scroll-timeline revealTimeline {
source: auto;
scroll-offsets: 0%, 100%;
}
@keyframes reveal {
from { opacity: 0; transform: translateY(50px); }
to { opacity: 1; transform: translateY(0); }
}
.section {
animation: reveal 1s ease-out;
animation-timeline: revealTimeline;
animation-range: entry 0% exit 100%;
}β Smooth reveal as each section appears on screen.
β Fully native, no JS scroll listeners needed.
β οΈ Browser Support
- β Chrome 115+
- β Edge 115+
- β Safari (partially supported via flags)
- β Firefox (not supported yet)
Note
π§ Best Practices
- Use @scroll-timeline for performance β avoid JS scroll events
- Donβt animate too many elements at once
- Prefer transforms (GPU-friendly) over layout-changing properties
- Use timelines for parallax, reveal effects, and progress bars