Animation Advanced

Scroll-linked animations without a library

Fade-in-on-scroll used to mean IntersectionObserver, GSAP, or AOS.js. CSS can now trigger animations based on scroll position, zero JavaScript, smooth 60fps.

Old JS + CSS
1// scroll-reveal.js
2const obs = new IntersectionObserver(
3  (entries) => {
4    entries.forEach(e => {
5      if (e.isIntersecting)
6        e.target.classList.add('visible');
7    });
8  }
9);
10document.querySelectorAll('.reveal')
11  .forEach(el => obs.observe(el));
Modern
Pure CSS
1@keyframes reveal {
2  from { opacity: 0; translate: 0 40px; }
3  to   { opacity: 1; translate: 0 0; }
4}
5
6.reveal {
7  animation: reveal linear both;
8  animation-timeline: view();
9  animation-range: entry 0% entry 100%;
10}

11/* No JS. GPU-accelerated. */
animation-timeline: view()
↓ Scroll down ↓
First item fades in
Second item fades in
Third item fades in
You get the idea ✦
↑ Scroll back up ↑
🚀

GPU-accelerated

Runs on the compositor thread, 60fps guaranteed. No main-thread jank from JS observers or scroll handlers.

🚫

No JavaScript at all

Drop GSAP, AOS.js, or custom IntersectionObserver code. Entire scroll animation in 4 lines of CSS.

🔄

Reversible by default

Scroll back up and the animation reverses naturally. No need for "unobserve" or state management.

Browser Support
72%
Chrome Edge Opera Firefox 🔜
Lines Saved
11 → 4
JS + CSS → pure CSS
Old Approach
JS runtime
Main thread blocking
Modern Approach
Compositor
GPU-accelerated

How it works

animation-timeline: view() binds a standard @keyframes animation to the element's visibility in the scroll port. As the element scrolls into view, the animation progresses from 0% to 100%.

animation-range: entry 0% entry 100% means the animation plays fully during the "entry" phase, from the moment the element's edge appears to when it's fully visible. You can also use exit, cover, or contain ranges.

Since this uses the browser's animation engine (compositor thread), it's inherently smoother than any JavaScript approach that mutates styles on the main thread.

ESC