<div class="description panel solid center">
  <div><h1>Variable height stacked pinning</h1>
    <p>Use pinning to layer panels on top of each other as you scroll.</p>
    <div class="scroll-down">Scroll down<div class="arrow"></div></div>
  </div>
</div>


<section class="panel purple">
	<h2 class="panel__number">1</h2>
</section>
<section class="panel" style="height: 220vh">
	<h2 class="panel__number">2</h2>
</section>
<section class="panel green" style="height: 50vh">
	<h2 class="panel__number">3</h2>
</section>
<section class="panel">
	<h2 class="panel__number">4</h2>
</section>



gsap.registerPlugin(ScrollTrigger);

let panels = gsap.utils.toArray(".panel");
// we'll create a ScrollTrigger for each panel just to track when each panel's top hits the top of the viewport (we only need this for snapping)
let tops = panels.map(panel => ScrollTrigger.create({trigger: panel, start: "top top"}));

panels.forEach((panel, i) => {
  ScrollTrigger.create({
    trigger: panel,
    start: () => panel.offsetHeight < window.innerHeight ? "top top" : "bottom bottom", // if it's shorter than the viewport, we prefer to pin it at the top
    pin: true, 
    pinSpacing: false 
  });
});

ScrollTrigger.create({
  snap: {
    snapTo: (progress, self) => {
      let panelStarts = tops.map(st => st.start), // an Array of all the starting scroll positions. We do this on each scroll to make sure it's totally responsive. Starting positions may change when the user resizes the viewport
          snapScroll = gsap.utils.snap(panelStarts, self.scroll()); // find the closest one
      return gsap.utils.normalize(0, ScrollTrigger.maxScroll(window), snapScroll); // snapping requires a progress value, so convert the scroll position into a normalized progress value between 0 and 1
    },
    duration: 0.5
  }
});
Run Pen

External CSS

  1. https://codepen.io/GreenSock/pen/xxmzBrw.css

External JavaScript

  1. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js?r=cahcebustin
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/ScrollTrigger.min.js
  3. https://codepen.io/GreenSock/pen/7ba936b34824fefdccfe2c6d9f0b740b.js