2 min read

CSS Scroll-Driven Animations

CSS Scroll-Driven Animations allow you to link the progress of an animation to the scroll progress of a scroll container. This enables effects like parallax backgrounds, reading progress bars, and image reveals without needing JavaScript scroll listeners.

1. The Concept

Traditionally, CSS animations run based on time (animation-duration). Scroll-driven animations replace the time dimension with a timeline.

  • Scroll Progress Timeline: Linked to the scroll position of a container (0% at top, 100% at bottom).
  • View Progress Timeline: Linked to the visibility of a specific element within the scrollport (0% when entering, 100% when leaving).

2. animation-timeline

This property links an animation to a timeline.

Scroll Progress Timeline (scroll())

Use scroll() to create an anonymous scroll progress timeline.

/* Create a progress bar at the top of the page */
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 10px;
  background: red;
  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll(); /* Defaults to nearest scroll ancestor (usually root) */
}

@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

View Progress Timeline (view())

Use view() to animate an element based on its own position in the viewport.

/* Fade in an image as it scrolls into view */
img {
  animation: fade-in linear;
  animation-timeline: view();
  animation-range: entry 0% cover 40%; /* Start when entering, finish when 40% visible */
}

@keyframes fade-in {
  from { opacity: 0; scale: 0.8; }
  to { opacity: 1; scale: 1; }
}

3. animation-range

This property defines where on the timeline the animation starts and ends.

  • entry: The range during which the element is entering the scrollport.
  • exit: The range during which the element is leaving the scrollport.
  • cover: The full range from first entering to fully leaving.
  • contain: The range where the element is fully inside the scrollport.
/* Animate only while the element is exiting the screen */
animation-range: exit 0% exit 100%;

4. Named Timelines

You can define a timeline on a container using scroll-timeline-name or view-timeline-name and reference it elsewhere.

programming/css/css programming/css/transitions-and-animations programming/css/scroll-snap programming/javascript/vanilla/animation-worklet-api