use UI

Scroll Animation Playground

See what animation-timeline: scroll() and view() actually do, adjust the range, and copy CSS that degrades honestly. No observers, no scroll listeners — the browser handles it.

Checking whether this browser supports scroll-driven animations…

Effect

Runs while the element crosses the bottom edge — good for reveals.

Playground

Scroll inside the frame below

Keep scrolling — the cards below animate as they pass through.

Output

CSS
.reveal {
  animation: reveal linear both;
  animation-timeline: view();
  animation-range: entry-crossing 0% entry-crossing 100%;
}

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Where this is unsupported the animation never runs and the element
   stays in its unanimated state — never hide content in the from state. */
@supports not (animation-timeline: view()) {
  .reveal {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    animation: none;
  }
}

Frequently asked

What is the difference between scroll() and view()?

scroll() tracks how far a scroll container has been scrolled — useful for a reading progress bar, where the value maps to the whole page. view() tracks a single element's journey through the viewport, which is what you want for reveals: each element animates on its own as it passes.

What does animation-range change?

It decides which part of that journey the animation covers. entry-crossing runs while the element crosses the bottom edge, which suits reveals. cover spans the entire pass through the viewport. contain only runs while the element is fully visible — and never runs at all if the element is taller than the viewport, which is a common surprise.

What happens in browsers that do not support it?

The animation simply never runs and the element stays wherever its unanimated styles put it. This is the thing to design around: never hide content in the from state and rely on the animation to reveal it, or it stays invisible. The exported CSS includes an @supports guard for exactly this reason.

Is this better than an IntersectionObserver?

For visual effects, yes — it runs off the main thread, needs no JavaScript, and stays in sync with the scroll position rather than firing once at a threshold. IntersectionObserver is still the right tool when you need to run logic, like loading data or sending analytics.

Does it respect reduced motion?

Not on its own. Scroll-driven animation is still animation, and someone who has asked for less motion should get less of it. The exported CSS turns it off under prefers-reduced-motion.

Related tools