πŸ“œ Mastering @scroll-timeline in CSS

πŸ“Œ 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.

>>β€œWith @scroll-Timeline, TimelineItem, the user becomes the timeline β€” scrolling drives the animation.”

🧩 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

PropertyDescription
sourceThe scroll container (default: viewport)
orientationblock (vertical) or inline (horizontal)
scroll-offsetsDefines 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

Always test scroll-linked animations on multiple browsers. Provide graceful fallbacks where necessary.

🧠 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

πŸ”— Helpful Resources

>>β€œScroll-driven animations make interfaces feel alive β€” @scroll-timeline gives you native power with zero JavaScript.” ✨