Jump to content


Multiple stacked sections using Scrolltrigger and different timelines for each section

Recommended Posts



I've been a little stumped with this and would love some help please. I've put together a pen using parts from other pens. Here's what I'm trying to do. I want to have 4 sections within a section container. I want the section container height to be 100vh and the child sections height to be 100% of the parent. I want all of the sections to be stacked on top of each other and their z-index to start at 1 and increase by their stacking order and positioned absolute. As the user scrolls down I want the next section to fade in and be able to do different things to elements within each section from its timeline. An example is in #section-2. I would like the div ".wave-transition" to slide up from below the bottom to act as a reveal so it covers up #section-1. So basically as the user scrolls down, I can reveal the next section and have different elements do different things. Any help would be appreciated.




See the Pen rNrYVNr by visual23 (@visual23) on CodePen

Link to comment
Share on other sites

It looks to me like your initial pin is a section or two too short (you're starting your animations after a VH scroll, so it's unpinning too soon.

end: `${window.innerHeight * (sections.length + 2)}px bottom`,

helps fix this so that all your animations complete during the scroll trigger. 

As for the wave-transition, I'm not entirely sure what you're going for here... This example may be helpful: 

See the Pen BaowPwo by GreenSock (@GreenSock) on CodePen


  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Hi elegantseagulls,


Thanks so much for taking the time to help me. I added your update to the pen but it still doesn't seem to be firing soon enough. This code below confuses me. Does that all look right?


sections.forEach((section, i) => {

  timelines[i] = gsap.timeline({
  scrollTrigger: {
    trigger: `#section-${i + 1}`,
    start: () => {
      console.log('start', window.innerHeight * i);
      return `top+=${window.innerHeight * i} top`
    end: () => {
      console.log('end', window.innerHeight * (i + 1));
      return `${window.innerHeight * (i + 1)} top`
    scrub: true,
    markers: true,
    id: `section-${i}`,

I think I can easily get the "wave-transition" part going after the other part is correct.



Link to comment
Share on other sites



What might be happening is: understanding how timeline position parameters work, each .to or .from gets chained together, unless you add a position parameter. More here: 



Try this, maybe?

timelines[1].to('#section-2', {
  backgroundColor: 'red',
  duration: 1,
  opacity: 1
.to('#section-2 .wave-transition', {
    yPercent: -100,
}, 0)


  • Like 2
Link to comment
Share on other sites



I was able to figure out the big issues by breaking out the timeline creation from the foreach and now I have more control over everything. I think the code I found was flawed so that was messing me up. It all makes sense now.


Thanks you for the info about the chained to or from!


I really appreciate your help. GSAP Rocks!


  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.