Scroll Parallax Layers — Free GSAP ScrollTrigger Snippet

Scroll Parallax Layers · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Data-driven speeds
One data-speed attribute per layer.
Single wiring loop
All layers tweened from one forEach.
Full-scene scrub
Parallax plays while the scene is in view.
Transform-only
yPercent composites on the GPU.
Depth cue
Differential speed reads as distance.
Embedded title
Mid-speed headline sits within the scene.
Reversible
Layers separate and rejoin both ways.
Asset-free demo
Gradient layers, swap for images.

About this UI Snippet

Scroll Parallax Layers — Depth From Speed-Differentiated Layers

Screenshot of the Scroll Parallax Layers snippet rendered live

Scroll parallax is the depth illusion where background layers drift slowly and foreground layers move quickly as you scroll, so the scene feels three-dimensional. This snippet builds a multi-layer parallax scene with GSAP and ScrollTrigger (from a CDN), driven entirely by a single data-speed attribute per layer.

Speed as data

Every parallax layer declares how fast it should move with a data-speed value — small numbers for distant layers (sky), larger ones for near layers (foreground). The script reads each value and creates a tween that translates the layer by yPercent: -40 × speed as the scene scrolls. Encoding speed in markup means adding or retuning a layer is a one-attribute change, and one loop wires them all up; there are no per-layer constants buried in the JavaScript.

Scrubbed across the scene

Each layer's tween is tied to a ScrollTrigger on the scene with start: 'top bottom' and end: 'bottom top', so the parallax plays across the entire time the scene is in view — from when its top enters the bottom of the viewport to when its bottom exits the top. scrub: true binds the motion to the scrollbar so the layers separate and re-converge smoothly as you scroll either direction. ease: 'none' keeps the speed differences constant and predictable.

Why differential speed reads as depth

Our eyes infer distance from motion parallax: things farther away appear to move less. By moving the sky a little and the foreground a lot for the same scroll, the snippet reproduces that cue, and the brain reads the flat layers as receding into space. The headline sits at a middle speed so it feels embedded in the scene rather than pasted on top.

Transform-only and smooth

All movement is yPercent (a GSAP transform), so the browser composites the layers on the GPU without reflowing or repainting layout — essential when several layers animate at once on every scroll frame. will-change: transform and overflow: hidden on the scene keep the moving layers contained and jank-free.

Asset-free scene

The layers are built from CSS radial gradients (sky glow, rolling hills, foreground ridge) so the snippet needs no images. In production you'd swap each layer's background for a transparent PNG or SVG; the parallax logic is unchanged because it only animates transforms.

Customizing it

Add more layers with their own data-speed, change the base travel multiplier, swap the gradients for real art, or add horizontal parallax with xPercent. Pair it with a parallax hero, a scroll zoom hero, or a hero parallax grid.

Step by step

How to Use

  1. 1
    Add the GSAP CDNsInclude gsap and ScrollTrigger from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSA layered scene renders between two spacers.
  3. 3
    Scroll through the sceneLayers move at different speeds for depth.
  4. 4
    Scroll back upThe layers re-converge — motion is scrubbed.
  5. 5
    Retune a layerChange its data-speed value.
  6. 6
    Use real artSwap each layer's gradient for a PNG/SVG.

Real-world uses

Common Use Cases

Hero scenes
A richer parallax hero.
Landing depth
Pair with a scroll zoom hero.
Showcases
Combine with a hero parallax grid.
Storytelling
Set scenes in a scroll pin story.
Game/landing
Layer art behind a startup hero.
Transitions

Got questions?

Frequently Asked Questions

Every layer carries a data-speed value, and the script reads it and tweens the layer by yPercent: -40 times that speed. Small values move distant layers a little; large values move near layers a lot. Encoding speed in the attribute means one loop wires every layer and retuning is a single-attribute change.

Each tween is tied to a ScrollTrigger on the scene with start: top bottom and end: bottom top, so it runs the whole time the scene is in view — from its top entering the viewport bottom to its bottom leaving the top. scrub: true binds it to the scrollbar so layers separate and re-converge as you scroll either way.

Motion parallax is a real depth cue: distant objects appear to move less than near ones. Moving the sky slightly and the foreground a lot for the same scroll reproduces that cue, so the brain reads the flat layers as receding into space. The headline uses a middle speed so it feels embedded in the scene.

Yes, because all movement is yPercent, a transform, so the browser composites the layers on the GPU without reflowing or repainting layout. will-change: transform promotes them and overflow: hidden on the scene contains them, so even multiple layers moving every frame stay smooth.

Render the layers with their data-speed attributes, then in a mount effect register ScrollTrigger and loop the layers (via a scoped ref query) to create the tweens. Return a cleanup that reverts the GSAP context so the triggers are removed on unmount. Swap gradients for image layers; the transform-based logic and CSS port unchanged.