Jump to content
Search Community

Accordion style pined headings

Sundararajan KS test
Moderator Tag

Go to solution Solved by Thomas Günther,

Recommended Posts

Hello,

I am brand new to GSAP (started yesterday) and I am trying to create an animation/scroll trigger like on this website https://www.bertani.net/style/ from the section "Bertani styles" in my current project. The closest I could find is this -  , but this is not same as on the above reference site.

 

Here, the heading is pinned on scrolled and on further scroll the image is also pinned and the next heading scrolls up as a layer and the image is pinned again and on scroll the next heading with image shows up as a layer and so on.

 

Can anyone help me here please?

 

See the Pen gOWVvzy by sundararajanks (@sundararajanks) on CodePen

Link to comment
Share on other sites

 

Hey @Sundararajan KS - welcome to the forum.

 

If you want the headings to each be visible but their content collapsed (except for the first one) like on the website you linked to, you will likely have to do some tweening on their height on scroll, simply just pinning won't be enough here.

 

For that I would probably first set things up via CSS, so the first item appears to be open with the other panels having a height of 100px e.g. respective to the height of the headline I set in the demo below - and calc the height for the first (open) item, so everything fits into 100vh.

 

With ScrollTrigger I would then pin a surrounding container once instead of each item seperately and via a scrubbing timeline with tweens on the height of the respective items, spaced out along the timeline via the position parameter, you could then achieve that accordeon like effect.

 

Maybe something like this - please note that this is not supposed to be undestood as the definitive way to go with this, but just as an example of an approach. Hope it helps though.

 

See the Pen 73791fb5b4eb4c770e8c33667584c37b by akapowl (@akapowl) on CodePen

 

 

  • Like 5
Link to comment
Share on other sites

In my example you could add another tween on the last visible item's height, and to prevent the white space showing (which is the pin-spacer's background showing, I suppose) you could e.g. set the subsequent content up by tweaking its marginTop with a negative amount respective to the space neccessary to cover up that white space. In addition you would of course also have to tweak the duration of the pinning scrollTrigger.

 

The tweaking of the latter was just trial and error for me now as I'm a bit in a hurry, so I can not give you a proper explanation on those numbers used; meaning: if you wanted to adjust the number of items/tweens in that example, you would have to give some thought about the values yourself.

 

This here seems to be working fine for now though:

 

See the Pen 6724603a9d1d4d0a6a216fee1bdee0ef by akapowl (@akapowl) on CodePen

 

 

  • Like 2
Link to comment
Share on other sites

Hey Sundararajan

I've simplified down @Thomas Günther's example for you.

(Not that it needed changing, it's great - but as you're new to GSAP I thought it might help to *just* focus on the bare bones of the interaction you're trying to get working)

 

I see you picked up on Thomas's pattern of adding a timeline to the drawer object drawer.tl.to - and I just wanted to point out that you don't have to do that for every timeline. You won't find that pattern anywhere in the docs, so it could lead to confusion.

You wrote...
 

const drawer_last = document.querySelector(".drawer_content_last");

drawer_last.tl = gsap.timeline({
  scrollTrigger: {
    scrub: 1,
  }
});


drawer_last.tl.to(drawer_last, {
  height: "auto",
  autoAlpha: 1
});

// this would usually be written like...

let drawerTl = gsap.timeline({
  scrollTrigger: {
    scrub: 1,
  }
});

drawerTl.to('.drawer_last', {
  height: "auto",
  autoAlpha: 1
});


Here's a simplified codepen with the drawers open first and closing on scroll, and markers to show you what's happening. It's always handy to start small and layer up as you understand what's going on or things can get knotty really quickly!

Does this help?

See the Pen yLXLBpL?editors=0010 by GreenSock (@GreenSock) on CodePen

  • Like 5
Link to comment
Share on other sites

Are you looking for pinSpacing:false ?

Make sure to check out the docs - a lot of the answers can be found in there!

 

pinSpacing Boolean | String - By default, padding will be added to the bottom (or right for horizontal: true) to push other elements down so that when the pinned element gets unpinned, the following content catches up perfectly. Otherwise, things may scroll UNDER the pinned element. You can tell ScrollTrigger not to add any padding by setting pinSpacing: false. If you'd rather it use margin instead of padding, you can set pinSpacing: "margin". Note: pinSpacing works in most cases, but it really depends on the way you set up your DOM and CSS. For example, if you pin something in a parent that has display: flex or position: absolute, the extra padding won't push other elements down/right so you may need to manually space things out. pinSpacing is just a convenience that works in most situations.
Link to comment
Share on other sites

You can also set the height of the accordion to auto with an !important flag. It's a bit hacky though.

See the Pen abwbvwY?editors=0110 by GreenSock (@GreenSock) on CodePen



The strength of scrollTrigger is that its very flexible - but there's not going to be a 'one-size-fits-all' solution.


There are a lot of pens in this thread that will get you most of the way - but some CSS tweaks and logic tweaks will be needed to perfect it.

I'm sure akapowl is working on a great solution as we speak, but it's a bit beyond the scope of these forums to provide completely perfected solutions for people. We're here to help get you set on the right path and answer GSAP-specific questions.

  • Like 1
Link to comment
Share on other sites

Hey,

 

You could possibly try this variant

 

// Pin the accordion and move space
gsap.timeline({
  scrollTrigger: {
    trigger: ".accordion",
    pin: true,
    start: "top top",
    end: "bottom bottom",
    endTrigger: "body",
    scrub:0.5,
    invalidateOnRefresh: true,
    markers: true
  }
})
  .to('.space02', {marginTop:-320, duration:1, ease:'none'})

 

Does that help?

 

Happy tweening ...

Mikel

  • Like 1
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.
×
×
  • Create New...