Scroll Reveal Grid — Free GSAP ScrollTrigger Staggered Grid

Scroll Reveal Grid · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Single from tween
Lands cards at their grid positions.
Grid-aware stagger
Diagonal wave reads the live layout.
Early trigger
Starts at top 75% before full view.
Replay on re-enter
toggleActions reverses then replays.
GPU motion
Only transform and opacity animate.
Eased settle
power3.out decelerates each card.
Responsive grid
auto-fill columns adapt by width.
Proportional cards
aspect-ratio keeps shape at any count.

About this UI Snippet

Scroll Reveal Grid — Cards That Rise in With a Staggered Wave

Screenshot of the Scroll Reveal Grid snippet rendered live

The scroll reveal grid is the portfolio or feature grid where cards lift up and fade in one after another as the section scrolls into view, instead of appearing all at once — the polished entrance on agency and product pages. This snippet builds it with GSAP and ScrollTrigger (from a CDN), plus a responsive CSS grid.

One tween, many cards

A single gsap.from animates every card from y: 60 and opacity: 0 up to its resting state. Using from means GSAP records each card's natural position, animates it out of that offset state, and lands it exactly where the CSS grid placed it — so you never hard-code final positions, and the reveal works no matter how the responsive grid wraps.

Grid-aware stagger

The magic is stagger: { each: 0.08, grid: 'auto', from: 'start' }. With grid: 'auto', GSAP reads the cards' actual row-and-column layout and offsets each card's start time based on its position, producing a diagonal wave that ripples across the grid rather than a flat left-to-right list. each: 0.08 sets the gap between cards; from: 'start' begins the wave at the top-left. This is the difference between a generic fade and a reveal that feels choreographed to the layout.

Triggered once, reversible

The ScrollTrigger fires at start: 'top 75%' — when the grid's top reaches 75% down the viewport, so the cards begin revealing just before they're fully in view. toggleActions: 'play none none reverse' plays the entrance on the way in and reverses it if you scroll the grid back out of view, so re-entering replays it cleanly without a manual reset.

Smooth, GPU-friendly motion

The animation only touches transform (the y offset) and opacity, both composited on the GPU, with power3.out easing so each card decelerates as it settles. will-change on the cards hints the compositor. Because nothing reflows, even a large grid reveals without jank.

Responsive grid underneath

The grid uses repeat(auto-fill, minmax(220px, 1fr)), so it reflows from one to several columns by width — and the grid-aware stagger adapts automatically, since it reads the live layout each time. The cards use aspect-ratio so they stay proportional at any column count.

Customizing it

Change the rise distance, the stagger spacing or origin ('center', 'edges'), the easing, or the trigger point; swap from for a scale or blur entrance. Pair it with feature cards, a portfolio filter grid, or stagger list.

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 JSAn intro, a card grid, and an outro render.
  3. 3
    Scroll to the gridCards rise and fade in as a diagonal wave.
  4. 4
    Scroll it out and backThe reveal reverses, then replays.
  5. 5
    Resize the windowThe grid reflows; the stagger adapts.
  6. 6
    Tune the waveChange stagger each, from, and easing.

Real-world uses

Common Use Cases

Portfolios
Feature sections
Animate feature cards in.
Galleries
Pair with a photo gallery.
Lists
A grid sibling of stagger list.
Team pages
Reveal a team card grid.
Products
Enter a product card grid.

Got questions?

Frequently Asked Questions

A single gsap.from animates every card from y: 60 and opacity: 0 to its resting state. Because from records each card's natural position and animates out of the offset, GSAP lands each card exactly where the CSS grid placed it — so you never hard-code final positions and the reveal works however the responsive grid wraps.

The stagger uses grid: auto, which tells GSAP to read the cards' real row and column layout and offset each card's start time by its position, producing a wave that ripples diagonally across the grid. each: 0.08 sets the spacing and from: start begins at the top-left, so it feels choreographed to the layout rather than a flat sequence.

Yes. toggleActions: play none none reverse plays the entrance when the grid enters and reverses it when the grid leaves the top, so scrolling away and back replays the reveal cleanly without a manual reset. The trigger fires at top 75%, so cards start animating just before they are fully in view.

It does, because grid: auto reads the live layout when the animation runs. The CSS grid uses auto-fill columns that reflow by width, and the grid-aware stagger adapts to whatever row and column arrangement is current, so the diagonal wave stays correct from one column on mobile to several on desktop.

Render the grid, then in a mount effect register ScrollTrigger and create the gsap.from on the cards scoped to a container ref (use gsap.context or a scoped selector). Return a cleanup that reverts the context so triggers are removed on unmount. If the list is dynamic, recreate or refresh ScrollTrigger after the items render. The CSS ports unchanged.