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.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to puzzle out the stagger configuration on your own. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the grid: auto stagger option reads the cards' real row and column positions to produce a diagonal wave instead of a flat sequential list, or why using gsap.from rather than a manual keyframe lets the reveal land cards at whatever position the responsive CSS grid actually placed them. The same assistant can help optimize it — asking whether toggleActions: play none none reverse is the right choice for a grid with dozens of cards versus play none none none, or whether the stagger's each value should scale down as card count grows. It's also useful for extending the effect: ask it to add a filterable category system that re-triggers the reveal for the visible subset, swap the rise-and-fade for a scale-and-blur entrance, or make the wave originate from the center instead of the start. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll reveal grid" card entrance effect in plain HTML, CSS, and JavaScript using GSAP with its ScrollTrigger plugin (load both from a CDN).

Requirements:
- A CSS grid of card elements using repeat(auto-fill, minmax(220px, 1fr)) so the number of columns responds to viewport width, with each card given a fixed aspect-ratio so cards stay proportional regardless of column count.
- A single gsap.from call (not one tween per card) targeting all cards, animating them from an offset y position and opacity 0 up to their natural resting position and full opacity — do not hardcode each card's final x/y position, since the CSS grid must remain the single source of truth for layout.
- Use GSAP's stagger option in its object form with grid set to auto (not a fixed row/column number) so GSAP detects the actual grid layout at animation time and offsets each card's start time based on its real row and column position, producing a diagonal reveal wave rather than a left-to-right list order.
- Attach a single ScrollTrigger to the grid container with a start point of roughly when the grid's top is 75% down the viewport (before it's fully in view) and toggleActions set to play the reveal on enter and reverse it if the grid scrolls back out of view, so re-scrolling into the grid replays the animation cleanly.
- Only animate transform-based properties (the y offset) and opacity so the reveal stays GPU-composited with no layout reflow, and use an easing curve that decelerates into the resting position (e.g. a power3 out ease) rather than linear motion.
- Confirm resizing the browser window, which changes how many columns the auto-fill grid produces, does not break the diagonal wave — since grid: auto re-reads the live layout each time the animation is triggered.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

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.
Related: Scroll Velocity Motion Blur
See the Scroll Velocity Motion Blur for a related scroll pattern worth pairing with this one.

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.