<body>
  <header>
    <div>
      <h1>Stacking Cards Animation</h1>
      <p>Scroll down to stack the cards. Scroll back up to unstack them.</p>
    </div>
  </header>
  <main>
    <ul id="cards">
      <li class="card" id="card-1">
        <div class="card-content">
          <div>
            <h2>Card One</h2>
            <p>This is the content of card one. Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
          </div>
          <figure>
            <img src="https://assets.codepen.io/210284/flower-9.jpg" alt="card-one">
          </figure>
        </div>
      </li>

      <li class="card" id="card-2">
        <div class="card-content">
          <div>
            <h2>Card Two</h2>
            <p>This is the content of card two. Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
          </div>
          <figure>
            <img src="https://assets.codepen.io/210284/flower-8.jpg" alt="card two">
          </figure>
        </div>
      </li>

      <li class="card" id="card-3">
        <div class="card-content">
          <div>
            <h2>Card Three</h2>
            <p>This is the content of card three. Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
          </div>
          <figure>
            <img src="https://assets.codepen.io/210284/flower-7.jpg" alt="card three">
          </figure>
        </div>
      </li>

      <li class="card" id="card-4">
        <div class="card-content">
          <div>
            <h2>Card Four</h2>
            <p>This is the content of card four. Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
          </div>
          <figure>
            <img src="https://assets.codepen.io/210284/flower-6.jpg" alt="card four">
          </figure>
        </div>
      </li>
    </ul>
  </main>
</body>
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;700&family=DM+Mono:wght@400;500&display=swap');

:root {
  --card-height: 40vw;
  --card-margin: 4vw;
  --card-top-offset: 1em;
  --numcards: 4;
  --outline-width: 0px;
}

body {
  background: #131212;
  color: beige;
  text-align: center;
  padding-bottom: 20vh
}

header, main {
  width: 80vw;
  margin: 0 auto;
}

header {
  height: 35vh;
  display: grid;
  place-items: center;
  margin-bottom: 80px;
}

#cards {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: repeat(var(--numcards), var(--card-height));
  gap: var(--card-margin);
  padding-bottom: calc(var(--numcards) * var(--card-top-offset));
  margin-bottom: var(--card-margin);
}

#card-1 {
  --index: 1;
}

#card-2 {
  --index: 2;
}

#card-3 {
  --index: 3;
}

#card-4 {
  --index: 4;
}

.card {
  position: sticky;
  top: 0;
  padding-top: calc(var(--index) * var(--card-top-offset));
}

.card-content {
  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.1), 0 1em 2em rgba(0, 0, 0, 0.1);
  background: #fffaf2;
  color: #131212;
  border-radius: 2rem;
  overflow: hidden;
  display: grid;
  grid-template-areas: "text img";
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  align-items: stretch;
  padding: 1.4em;
}

.card-content > div {
  grid-area: text;
  width: 95%;
  max-width: 800px;
  place-self: center;
  text-align: left;
  display: grid;
  gap: 1em;
  place-items: start;
}

.card-content > figure {
  grid-area: img;
  overflow: hidden;
}

.card-content > figure > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: .4em;
}

h1 {
  font-weight: 300;
  font-size: 3rem;
  margin-bottom: 1rem;
  font-family: 'Cormorant Garamond', serif;
}

h2 {
  font-weight: bold;
  font-size: 2.5rem;
  font-family: 'Cormorant Garamond', serif;
  margin: 0;
}

p {
  font-weight: 300;
  line-height: 1.42;
  font-size: 1.1rem;
}

/* Animation */
@supports (animation-timeline: works) {

  @scroll-timeline cards-element-scrolls-in-body {
    source: selector(body);
    scroll-offsets:
      selector(#cards) start 1,
      selector(#cards) start 0
    ;
    start: selector(#cards) start 1;
    end: selector(#cards) start 0;
    time-range: 4s;
  }

  .card {
    --index0: calc(var(--index) - 1);
    --reverse-index: calc(var(--numcards) - var(--index0));
    --reverse-index0: calc(var(--reverse-index) - 1);
  }
  
  .card__content {
    transform-origin: 50% 0%;
    will-change: transform;

    --duration: calc(var(--reverse-index0) * 1s);
    --delay: calc(var(--index0) * 1s);

    animation: var(--duration) linear scale var(--delay) forwards;
    animation-timeline: cards-element-scrolls-in-body;
  }

  @keyframes scale {
    to {
      transform:
        scale(calc(
          1.1
          -
          calc(0.1 * var(--reverse-index))
        ));
    }
  }
}

External CSS

  1. https://codepen.io/tutsplus/pen/vYrpEwd.css

External JavaScript

This Pen doesn't use any external JavaScript resources.