View-Progress vs. Scroll Trigger

Scroll slowly — watch the difference. Left column fires once at 10% visible. Right column tracks your scroll position.

data-trigger="scroll"

binary · IntersectionObserver

Fires once

The browser detects this card at 10% visible, then plays a fixed 400ms animation. Scroll-speed has no effect.

binary · IntersectionObserver

Pre-baked timing

Identical to the first — author has no control over how the reveal maps to scroll position.

binary · IntersectionObserver

One-shot

Once it's played, scrolling back doesn't reset it. The state persists.

data-trigger="view-progress"

continuous · animation-timeline: view()

Tracks scroll

Opacity and translate are driven by view progress. Stop mid-scroll — the card stops mid-reveal.

continuous · animation-timeline: view()

Reversible

Scroll back up and the reveal reverses. It's genuinely tied to the element's position in the viewport.

continuous · animation-timeline: view()

Zero JS

Pure CSS via animation-timeline: view(). No requestAnimationFrame, no IntersectionObserver.