More Scroll Snippets
Scroll Zoom Hero — Free GSAP ScrollTrigger Zoom Hero Snippet
Scroll Zoom Hero · Scroll · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Scroll Zoom Hero — A Hero That Zooms as You Scroll Through It

The scroll zoom hero is the cinematic opener where the background image scales up and the headline drifts away as the visitor scrolls past — the "descend into the frame" effect on modern landing and editorial pages. This snippet builds it with GSAP and ScrollTrigger (loaded from a CDN), plus plain HTML and CSS, with no image assets required.
One scrubbed timeline
The whole effect is a single GSAP timeline tied to a ScrollTrigger with scrub: true, so every tween's progress is driven directly by the scroll position rather than time. Three tweens run in parallel from position 0: the media layer scales from 1 to 1.6, the copy lifts up and fades to zero, and a darkening overlay deepens. Because they share one scrubbed timeline, they advance in perfect lockstep with the scrollbar and reverse cleanly when you scroll back up.
Pinning without reserving space
The hero pins with pin: true and pinSpacing: false, so it stays fixed for one screen of scrolling while the section below slides up to meet it. Using pinSpacing: false means the pin doesn't add extra scroll height — the next section overlaps the pinned hero, producing the seamless handoff where the page content rises over the zooming image instead of leaving a gap.
Mapping the range
start: 'top top' begins the animation when the hero reaches the top of the viewport, and end: 'bottom top' finishes it after one viewport of scrolling. That one-screen range is the sweet spot: long enough to feel deliberate, short enough that the zoom completes before the hero is gone. ease: 'none' on each tween keeps the motion linear so it feels glued to the scroll.
The overscan trick
The media layer is inset by a negative margin (inset: -6%) so it's slightly larger than the hero. As it scales up, the zoom never reveals an edge, and the starting state already hides the overscan — a small but essential detail for any scroll-zoom so the image always fills the frame. will-change: transform promotes the layer to its own compositor layer for smooth scaling.
Asset-free, drop-in ready
So the snippet runs with zero downloads, the "photo" is built from layered CSS gradients plus a dotted texture. In production you'd swap the .zh-media background for a real background-image; the timeline is identical because it only animates transform and opacity, which work on any background.
Customizing it
Change the zoom amount, the copy's exit direction, the overlay strength, or the scroll range via end. Add a parallax layer or a second line of copy that enters as the first leaves. Pair it with a scroll horizontal pin, a scroll image mask, or a parallax hero.
Step by step
How to Use
- 1Add the GSAP CDNsInclude gsap and ScrollTrigger from the CDN panel.
- 2Paste HTML, CSS, and JSA full-screen hero and a section below render.
- 3Scroll downThe background zooms and the headline lifts away.
- 4Scroll back upEverything reverses — the timeline is scrubbed.
- 5Use a real imageSet background-image on the .zh-media layer.
- 6Tune the zoomChange the scale target and the end range.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
All three movements live on one GSAP timeline tied to a ScrollTrigger with scrub: true, starting at position 0. The media scales, the copy lifts and fades, and the overlay deepens together, so they advance in lockstep with the scrollbar and reverse cleanly on scroll-up. scrub makes scroll position, not time, drive the progress.
Pinning normally adds scroll height equal to the pin duration, which would leave a gap. pinSpacing: false pins the hero without reserving that space, so the section below slides up and overlaps the zooming hero. This produces the seamless handoff where page content rises over the image rather than appearing after an empty stretch.
The media layer is inset by -6% so it overscans the hero. As it scales up, the zoom never exposes an edge, and even at the start the extra is clipped out of view. Without this overscan, scaling could reveal the layer's boundary; will-change: transform also promotes it for smooth GPU scaling.
start: top top begins when the hero hits the top of the viewport and end: bottom top finishes after one viewport of scrolling, so the zoom plays across a single screen. Increase the end distance (for example +=150%) to slow it down and make the descent feel longer.
Register ScrollTrigger once and build the timeline in a mount effect (useGSAP/useLayoutEffect, onMounted, or ngAfterViewInit) scoped to a ref for the hero. Return a cleanup that reverts the GSAP context or kills the ScrollTriggers so the pin is removed on unmount and navigation. Swap the media background for an image; the CSS and timeline port unchanged.