Jump to content
Search Community

SmoothScroller issue with native vertical CSS snap

ghisleouf test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi there,

 

Hope you are fine.

I'm struggling a little with SmoothScroller. I figured out that I had an issue with it when using native CSS Snap properties.

As you can see in the codepen demo, I'm sending a "onUpdate" message in the console which is supposed to be printed out on scroll.

When my CSS code is applied, it does not work, which seems to be normal, regarding theheight:100vh property I've set.

 

If someone has a solution for me, that would awesome! I would like to keep native CSS snapping and avoid JS library for it.

 

Thanks a lot for your precious help! 🤘

 

See the Pen MWzybex by ghislefou (@ghislefou) on CodePen

Link to comment
Share on other sites

Yeah, that's because ScrollSmoother uses the native scrolling on the <body> to work, but you're creating a custom container element that's doing the scroll just inside that element. That approach is fundamentally incompatible. 

 

However, if you understand how ScrollSmoother works (by making the wrapper element position: fixed and then using the <body> scroll position to control where it translates the content smoothly), you could build a solution here by basically making a copy of those snapping elements, make them visibility: hidden, put them OUTSIDE the wrapper, and then use the <body> for the snapping like this: 

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

 

Does that help? 

  • Like 1
Link to comment
Share on other sites

Hi,

 

You don't have to completely duplicate the DOM elements and their contents, just the dimensions and positions, nothing more.

 

If you inspect the codepen example by Jack, you'll see that the elements with the snap-only class have visibility hidden, so they're not visible and you don't have to include all the content in them, just the positions and sizes.

 

Happy Tweening!

Link to comment
Share on other sites

So… for now, I'm getting the « onUpdate » message triggered, on my real project, but, I can’t get the sections snapped … 

I think I'm missing something simple !

Let me share a Stackblitz  project example URL here: https://stackblitz.com/edit/js-yvytxj?file=src%2Fpage.js

 

Thanks a lot for your amazing help !

 

Edited by ghisleouf
Add project demo url
Link to comment
Share on other sites

It looks like you removed all the classes from the copied elements and then applied ones that messed things up. Your elements had display: none, so they were completely taken out of the document flow and couldn't initiate any snapping, and they had a height of 0. 

 

Just make sure they have the appropriate CSS so they mimic the sizes of your real sections, but visibility: hidden

https://stackblitz.com/edit/js-pucgaz?file=src%2Fpage.js,index.html

Link to comment
Share on other sites

Yeah, by default ScrollSmoother doesn't do any smoothing on mobile devices. You can set smoothTouch: 0.1 or something if you'd like it to just do a little bit. I don't know why your added divs would be visible if you've got visibility: hidden on those. Are you sure? I'd have to see your exact code in a minimal demo to understand why, but it sounds like an issue in the way you implemented it. 🤷‍♂️

Link to comment
Share on other sites

That's strange ... I'm thinking it's related to the css classes applied on the smoother and content div, that are not overriden by ScrollSmoother. As a result, CSS snap is not working ... I can confirm that I have the same result on both (yours and mine) StackBllitz links.

I cannot apply a CSS media query because of iPad screen for example.

 

If you have any idea, that would be awesome.

 

Thanks a lot.

Link to comment
Share on other sites

  • Solution

Oh, right, that totally makes sense. On mobile, ScrollSmoother doesn't apply any smoothing at all, so it doesn't set position: fixed on that wrapper, etc. So when you add stuff to the DOM, it's just getting added further down the page whereas when ScrollSmoother is active/smoothing, it sets position: fixed on the wrapper meaning all the added elements would be BEHIND that. So you can just sense if it's a touch device and skip doing all that copying: 

ScrollTrigger.isTouch || copySnapToBody();

https://stackblitz.com/edit/js-pucgaz?file=src%2Fpage.js

 

Better? 

  • Like 2
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...