Scroll zoom-out image

An image starts slightly zoomed in and settles to 1:1 as it scrolls into view, bound to scroll position.

ScrollScroll progress CSS scroll-timelineGSAP scroll-progress-based Targets: Web · App Chrome/Edge 115+, Safari 26+, Firefox behind flag; JS fallback included
Scroll inside the frame ↕
Target
Implement the "Scroll zoom-out image" effect in vanilla HTML/CSS/JS.

Context: An image starts slightly zoomed in and settles to 1:1 as it scrolls into view, bound to scroll position.
Trigger: the page scrolls; progress is bound to scroll position, not time.
Timeline: scroll-progress-based (map scroll position to animation progress; no fixed duration).

Motion tokens (normal):
- scale: 1.18 → 1
- opacity: 0.4 → 1
- scroll range: entry 0% (image top enters) → cover 45%
- easing: linear

Motion tokens (prefers-reduced-motion):
- opacity: 0.4 → 1
- scroll range: entry 0% → cover 45%
- easing: linear

Technique: prefer CSS `animation-timeline: scroll()/view()` inside `@supports (animation-timeline: scroll())`, with a JS fallback; GSAP (ScrollTrigger where relevant) is acceptable as an alternative.

Acceptance:
- animate only transform and opacity unless the spec lists other properties
- no layout shift; content is visible without the animation
- when prefers-reduced-motion is set, use the reduced tokens only
- image container clips overflow so the zoom never changes layout
- progress reverses when scrolling back up

Generated from the spec. Prompts differ by target name only; the tokens are the source of truth.