Advertisement

GSAP ScrollTrigger List Expansion

| by Vladimir | 3 min read | code by Aaron Iker
Advanced

Tech & Dependencies

HTML SCSS JavaScript
GSAP ScrollTrigger

Features

  • ScrollTrigger
  • Card Stack Effect
  • CSS Clip-path
  • Responsive Mobile Mockup

Browser Support

Chrome 80+ Edge 80+ Firefox 75+ Safari 13.1+

Core

This snippet showcases a GSAP ScrollTrigger List Expansion effect. It mimics the native iOS “Notification Center” or “Wallet” card stack behavior. Its function is to condense a long list of items into a compact, layered visual stack, and then fluidly expand them into full, scrollable cards as the user scrolls down the container, creating a highly tactile mobile UI experience.

Specs

  • Weight: ~80 KB (Requires GSAP core and ScrollTrigger plugin).
  • Performance: Highly optimized. The GSAP timelines target CSS custom properties which are then mapped to hardware-accelerated transform and clip-path properties in the SCSS, preventing heavy layout thrashing during scroll.
  • Theming / Customization: Core colors are managed via CSS variables. The iPhone mockup wrapper drops away automatically on smaller screens (max-width: 500px) for a native full-screen experience.
  • Responsiveness: Designed primarily as a mobile view (width: 375px). On desktop, it renders inside a CSS-drawn iPhone frame.
  • Graceful Degradation: Relies heavily on GSAP and JavaScript. Without JS, the cards will render, but they will remain stuck in their initial, overlapped state, making the content unreadable.

Anatomy

The component uses a clever layering system to create the “stacked” illusion.

  • HTML (The Skeleton): An outer #phone container holds the .screen and status bar icons. Inside, the .content div acts as the scroll container. The .entries wrapper holds multiple <article> tags. Each article has a .compact (the folded top edge) and an .inner (the actual content).
  • CSS (The Skin): SCSS handles the complex transformations. The .entries article uses position: sticky to keep them anchored while scrolling. CSS variables set the initial stacked offset. clip-path is used to hide the bottom portion of the cards initially.
  • JS (The Nervous System): Iterates over the <article> nodes and uses GSAP.timeline and ScrollTrigger.create. It binds the scroll position to the animation of the CSS variables, causing the cards to un-clip, scale up, and un-rotate as they hit specific trigger points.

Logic

The standout technical implementation is the “Scroll-Scrubbed Custom Property Routing”.

function roll(content, article, articles, index) {
    let animation = timeline().to(article, {
        '--clip': `${article.offsetHeight + 112}px`,
        '--compact-s': 1,
        '--compact-o': 1,
        // ...
    });
    // ...
    return ScrollTrigger.create({
        animation,
        trigger: article,
        scroller: content,
        scrub: true,
        start: `top top+=184`,
        end: `bottom top+=112`
    });
}

Instead of letting GSAP directly manipulate inline styles like transform: translateY(...) (which can get messy when dealing with complex 3D rotations and clipping simultaneously), the script animates custom CSS variables. GSAP smoothly interpolates --clip from 0px to the full height of the article. The SCSS then reads clip-path: polygon(0 var(--clip), 100% var(--clip), ...) to reveal the card. Tying this timeline to a ScrollTrigger with scrub: true means the animation frame is inextricably linked to the user’s scrollbar position, allowing them to drag the animation forward and backward seamlessly.

Feel

Tactile, elastic, and deeply satisfying. The interaction feels less like scrolling a webpage and more like physically pulling apart a deck of cards. The use of position: sticky ensures the stack feels grounded, while the staggered rotation gives the folded cards a slight, messy realism before they snap perfectly into place. The dynamic header fading provides a polished cinematic finish to the scrolling journey.

Advertisement