Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Elliott W

Vertical CSS scroll snap

Recommended Posts

How do I replicate the smooth css snapping as demonstrated in this codepen:

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

 

But on the red boxes in my codepen, so that the top of a red box is always aligned with the top of the #text element.

 

Also how do I "unpin" #text after the top of the last red box is aligned with top of #text?

 

I will also need to attach scroll triggers to each red box, so that I can change the #text content on the right based on which box is currently in view. I think this restricts what I can specify as the "scroller".

 

See the Pen QWQZOEM by elliott-w (@elliott-w) on CodePen

Link to comment
Share on other sites

  • Elliott W changed the title to Vertical CSS scroll snap

Welcome to the forums, @Elliott W

 

It'd probably be best if you just focused on one thing at a time rather than creating a thread with a list of requirements :)

 

The CSS scroll snapping is pretty limited in browsers. I think it only works on direct children of the scroller. That's more of a CSS question. We really try to keep these forums focused on GSAP-specific questions. 

 

You could use ScrollTrigger's snapping capabilities but it can't behave the same as native CSS scroll snapping because ScrollTrigger needs to wait for the user to STOP scrolling before it can kick in the snapping animation, otherwise it may fight for control with the user. You'd need to create a ScrollTrigger for whole section of red boxes and then calculate the ratios for snapping. Please see the docs and give it a shot - if you get stuck, post your attempt back here or start a new thread. 

 

Here's a fork of your demo with some of the other stuff quickly demonstrated: 

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

 

Please keep in mind, though, that we don't typically do this sort of thing where people say "here are my list of requirements ___, please show me how to do it" and then do the work for them - I just had a little time and wanted to knock some of these parts out for you as a courtesy and to illustrate how it's done for others as well. 

 

Enjoy the tools! 👍

  • Like 1
Link to comment
Share on other sites

Hi Jack,

 

Thanks for the quick and detailed reply :)

 

I should clarify the biggest issue I was facing was the scroll snapping,  I tried my best for many hours, looking through every tidbit of gsap documentation and pretty much every related codepen I could get my hands on, but to no avail. I should also say I don't expect anybody to code the solution for me (thank you for the codepen though, helps a lot), just hoping for any pointers in the right direction.

 

The sort of snapping functionality I'm looking for is as follows:

 

1. User starts scrolling

2. User stops scrolling

3. Top of nearest red box starts snapping/aligning to top of text

 

But so far it seems gsap's builtin snapping can only do the following:

 

1. User starts scrolling

2. User stops scrolling

2.1. Red box must keep tweening to it's final position based on the inertia of scroll

3. Top of nearest red box starts snapping/aligning to top of text


It's the delay caused by step 2.1 that I'm trying to avoid.

 

I've also just realised that the very first codepen I posted behaves very differently when scrolling using apple trackpad/magic mouse vs a mechanical scroll wheel. Transitions are way smoother using the former. So I'm going to abandon the idea of using native css scroll snapping.

 

After doing some more digging, I think I may try something like this:

 

Except make the start and end point for each section inset so it doesn't immediately snap, but lets you scroll a little bit before snapping. I will post an updated codepen if I manage to get it working.

  • Like 1
Link to comment
Share on other sites

I couldn't help myself - I imagine this may assist others looking to do something similar so I went ahead and created this solution: 

 

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

 

The basic concept is to create a simple ScrollTrigger for each box and then use the "start" of each of those to calculate the 0-1-based progress value for snapping on the overall section ScrollTrigger. 

 

Does that help? 

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

You are simply a god amongst men. Thank you sooooo much!

 

I realised the snap behaviour is more flexible than I thought. I ended up setting the delay after user stops scrolling to 0 and making the transitions a bit smoother. Also I added a custom snapTo function, so that when a user scrolls down to this component for the first time, it doesn't immediately send them to box 2:

 

See the Pen abqQbQr by elliott-w (@elliott-w) on CodePen

 

Edit: Hmm actually this custom snapTo function doesn't take into account the direction of scroll. Are there any gsap util functions that do the same as if you had given the snap property an array?

Link to comment
Share on other sites

20 minutes ago, Elliott W said:

I ended up setting the delay after user stops scrolling to 0 and making the transitions a bit smoother.

FYI, the delay can't actually be 0. It'll end up being 0.1. It's basically impossible for it to fire IMMEDIATELY when the user stops because there must be some amount of time that it waits to make sure another "scroll" event doesn't get fired by the user (or "wheel" or "touchmove" or whatever). 

 

25 minutes ago, Elliott W said:

Hmm actually this custom snapTo function doesn't take into account final scroll position based on velocity or the direction of scroll. Are there any gsap util functions that do the same as if you had given the snap property an array?

I'm confused - it does do directional snapping by default. I'm not sure why you think it's not doing that. You can disable it by setting directional: false

 

The velocity thing is very tricky because as I said earlier, it can't apply snapping until the user STOPS scrolling (otherwise it may fight with the user) which means the velocity is almost zero at that point, so I don't know how you'd expect that to work. 

 

There are definitely GSAP tools for tracking and even smoothly continuing (and degrading) velocity (see InertiaPlugin) but I don't think that's really what you want here.

  • Like 1
Link to comment
Share on other sites

26 minutes ago, GreenSock said:

FYI, the delay can't actually be 0. It'll end up being 0.1

Ah okay, so the delay is basically the debounce timeout. Yeah I'll just use 0.1 then.

 

21 minutes ago, GreenSock said:

I'm confused - it does do directional snapping by default.

Yeah ScrollTrigger's built-in snap function does do directional snapping, but the custom one I provided didn't. I managed to find the ScrollTrigger.snapDirectional() function which does what I'm looking for:

 

See the Pen MWQzwYa by elliott-w (@elliott-w) on CodePen

 

Thank you very much for your help.

  • 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.
×