Copied SVG to clipboard
Something went wrong
Copied code to clipboard
Something went wrong
Saved to bookmarks!
Removed from bookmarks
Webflow Challenge: Win $5K

Default

User image

Default

Name

  • -€50
    Upgrade to Lifetime
The Vault/

Stacking Cards Parallax

Stacking Cards Parallax

Documentation

Webflow

Code

Setup: External Scripts

External Scripts in Webflow

Make sure to always put the External Scripts before the Javascript step of the resource.

In this video you learn where to put these in your Webflow project? Or how to include a paid GSAP Club plugin in your project?

HTML

Copy
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>

Step 1: Copy structure to Webflow

Copy structure to Webflow

In the video below we described how you can copy + paste the structure of this resource to your Webflow project.

Copy to Webflow

Webflow structure is not required for this resource.

Step 1: Add HTML

HTML

Copy
<div class="stacking-cards__collection">
  <div class="stacking-cards__list">
    <div data-stacking-cards-item="" class="stacking-cards__item is--green">
      <h1 class="stacking-cards__item-h"><span class="stacking-card__heading-faded">emerald</span><br>new beginnings</h1>
      <img src="https://cdn.prod.website-files.com/68a581f419b751517e3d40c0/68a58a5f107533572d9566ce_Glass%20and%20Marble%20Cube%20Composition.avif" data-stacking-cards-img="" class="stacking-cards__item-img">
      <div class="stacking-cards__item-top">
        <span class="stacking-card__top-span">Gemstones</span>
        <span class="stacking-card__top-span">01 / 05</span>
      </div>
    </div>
    <div data-stacking-cards-item="" class="stacking-cards__item is--purple">
      <h1 class="stacking-cards__item-h"><span class="stacking-card__heading-faded">amethyst</span><br>supports good health</h1>
      <img src="https://cdn.prod.website-files.com/68a581f419b751517e3d40c0/68a58a5ff31697ad7106fc1d_Minimalist%20Stacked%20Cubes%20(1).avif" data-stacking-cards-img="" class="stacking-cards__item-img">
      <div class="stacking-cards__item-top">
        <span class="stacking-card__top-span">Gemstones</span>
        <span class="stacking-card__top-span">02 / 05</span>
      </div>
    </div>
    <div data-stacking-cards-item="" class="stacking-cards__item is--blue">
      <h1 class="stacking-cards__item-h"><span class="stacking-card__heading-faded">sapphire</span><br>wisdom &amp; learning</h1>
      <img src="https://cdn.prod.website-files.com/68a581f419b751517e3d40c0/68a58a5fe3e373d4afe5f860_Stacked%20Cubes%20on%20Marble.avif" data-stacking-cards-img="" alt="" class="stacking-cards__item-img">
      <div class="stacking-cards__item-top">
        <span class="stacking-card__top-span">Gemstones</span>
        <span class="stacking-card__top-span">03 / 05</span>
      </div>
    </div>
    <div data-stacking-cards-item="" class="stacking-cards__item is--brown">
      <h1 class="stacking-cards__item-h"><span class="stacking-card__heading-faded">topaz</span><br>re-motivating</h1>
      <img src="https://cdn.prod.website-files.com/68a581f419b751517e3d40c0/68a58a5f732de55938114f5f_Minimalist%20Stacked%20Cubes.avif" data-stacking-cards-img="" class="stacking-cards__item-img">
      <div class="stacking-cards__item-top">
        <span class="stacking-card__top-span">Gemstones</span>
        <span class="stacking-card__top-span">04 / 05</span>
      </div>
    </div>
    <div data-stacking-cards-item="" class="stacking-cards__item is--red">
      <h1 class="stacking-cards__item-h"><span class="stacking-card__heading-faded">rose quartz</span><br>peace and love</h1>
      <img src="https://cdn.prod.website-files.com/68a581f419b751517e3d40c0/68a58a5ff1fd91f3ae23c706_Geometric%20Blocks%20Arrangement.avif" data-stacking-cards-img="" class="stacking-cards__item-img">
      <div class="stacking-cards__item-top">
        <span class="stacking-card__top-span">Gemstones</span>
        <span class="stacking-card__top-span">05 / 05</span>
      </div>
    </div>
  </div>
</div>

HTML structure is not required for this resource.

Step 2: Add CSS

CSS

Copy
.stacking-cards__collection {
  width: 100%;
}

.stacking-cards__list {
  flex-flow: column;
  display: flex;
}

.stacking-cards__item {
  color: #fff;
  border-top-left-radius: 1em;
  border-top-right-radius: 1em;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100vh;
  margin-top: -1em;
  padding-top: 5em;
  padding-bottom: 5em;
  display: flex;
  position: relative;
}

.stacking-cards__item.is--green {
  background-color: #1a261e;
}

.stacking-cards__item.is--purple {
  background-color: #544a58;
}

.stacking-cards__item.is--blue {
  background-color: #1a232e;
}

.stacking-cards__item.is--brown {
  background-color: #62594c;
}

.stacking-cards__item.is--red {
  background-color: #1f1715;
}

.stacking-cards__item-h {
  text-align: center;
  text-transform: uppercase;
  margin-top: 0;
  margin-bottom: 0;
  font-family: PP Neue Corp Tight, Arial, sans-serif;
  font-size: 10vw;
  font-weight: 700;
  line-height: .8;
}

.stacking-card__heading-faded {
  opacity: .5;
}

.stacking-cards__item-img {
  aspect-ratio: 1;
  border-radius: .75em;
  width: 30vw;
  margin-top: -1vw;
}

.stacking-cards__item-top {
  justify-content: space-between;
  align-items: center;
  display: flex;
  position: absolute;
  top: 2.5em;
  left: 2.5em;
  right: 2.5em;
}

.stacking-card__top-span {
  font-size: 1em;
  font-weight: 500;
}

Step 2: Add custom Javascript

Custom Javascript in Webflow

In this video, Ilja gives you some guidance about using JavaScript in Webflow:

Step 2: Add Javascript

Step 3: Add Javascript

Javascript

Copy
gsap.registerPlugin(ScrollTrigger);

function initStackingCardsParallax(){
  const cards = document.querySelectorAll("[data-stacking-cards-item]");
  
  if (cards.length < 2) return;

  cards.forEach((card, i) => {
    // Skip over the first section
    if (i === 0) return;
    
    // When current section is in view, target the PREVIOUS one
    const previousCard = cards[i - 1]
    if (!previousCard) return;
    
    // Find any element inside the previous card
    const previousCardImage = previousCard.querySelector("[data-stacking-cards-img]")
    
    let tl = gsap.timeline({
      defaults:{
        ease:"none",
        duration: 1
      },
      scrollTrigger: {
        trigger: card,
        start: "top bottom",
        end: "top top",
        scrub: true,
        invalidateOnRefresh: true
      }
    })
    
    tl.fromTo(previousCard,{ yPercent: 0 },{ yPercent: 50})
      .fromTo(previousCardImage,{ rotate: 0, yPercent:0 },{ rotate: -5, yPercent: -25 }, "<")
    
  });
}

document.addEventListener("DOMContentLoaded", () =>{
  initStackingCardsParallax();
})

Step 3: Add custom CSS

Step 2: Add custom CSS

Custom CSS in Webflow

Curious about where to put custom CSS in Webflow? Ilja explains it in the below video:

CSS

Copy

Implementation

Cards

The only element(s) required to make this setup work, are the cards you want to 'stack'. Give each card the [data-stacking-cards-item] attribute.

Parallax distance

If you want to change how dramatic the parallax effect is, you can change the yPercent value in the timeline:

// We currently move the card down by 50% of its own height
tl.fromTo(previousCard,{ yPercent: 0 },{ yPercent: 50})

Animate content in the cards

You can of course only have the cards 'stack' with the parallax effect. But, you can also animate any element inside the card. In our example, we tagged the image inside with [data-stacking-cards-img] so that we can add a tween to the timeline, and animate it.

If you want to add more (or different) items, simply give them an attribute of [data-stacking-cards-X]. With X being variable, give this a logical name. So if it's a heading you want to animate, it would become [data-stacking-cards-heading]. Then, make sure to create a variable for it in the function underneath our current image:

// Find any element inside the previous card
const previousCardImage = previousCard.querySelector("[data-stacking-cards-img]")
const previousCardHeading = previousCard.querySelector("[data-stacking-cards-heading]")

Then, add any tween to the timeline to animate it:

tl.fromTo(previousCard,{ yPercent: 0 },{ yPercent: 50})
  .fromTo(previousCardImage,{ rotate: 0, yPercent:0 },{ rotate: -5, yPercent: -25 }, "<")
  .fromTo(previousCardHeading,{ autoAlpha: 1 },{ autoAlpha: 0 }, "<")
  // Add more tweens as you wish

Some quick ideas

It was too much to show in a single demo, but some ideas that you can play with:

  • Fade out the previous card while it's having the parallax content
  • Fade out only an inner container, so the card remains, but the content fades out
  • While the parallax on the card is happening, try scaling it down as well.

Resource Details

GSAP
Scrolltrigger
Parallax
Card
Scrolling
Stacked

Original source

Ilja van Eck

Creator Credits

We always strive to credit creators as accurately as possible. While similar concepts might appear online, we aim to provide proper and respectful attribution.