Jump to content
GreenSock

JoeH

Scrolling stops suddenly near bottom of page when using ScrollSmoother, Bug on some devices?

Recommended Posts

This issue is only affecting some devices, the ones we have found that have an issue are Samsung  S22 Ultra using Chrome browser, Samsung browser and Firefox, and using an Amazon fire tablet with the Silk browser.

 

The scrollbar does not reach the bottom of the page, not sure if this helps or not in diagnosing the issue, but the scroll bar will not move once it gets to a certain point (around 7/8 of the way down the page on this particular webpage), the point it reaches also changes if you refresh, allowing you to scroll slightly further.

 

I have tried creating the smoother instance once the entire page has loaded and even adding a setTimeout function, but this does not work, and seems to break the pins and scroll triggers.

 

I don't have a codepen although I can try set one up, or I can provide a link to the website in which it is happening on, but would prefer to not share this in public.

 

Attached is a video showing the issue on mobile

 

 

 

 

Link to comment
Share on other sites

It would really help if you could provide a minimal demo - it doesn't need to be your actual project (in fact, we strongly prefer that it's NOT - we only want the simplest reproduction with as few elements and little code as possible). Got a CodePen? 

 

Also, can you tell us the value of document.documentElement.scrollHeight and document.body.scrollHeight in your project please? Do they match? If not, which one is bigger? 

  • Like 1
Link to comment
Share on other sites

Will try replicate in a codepen. 

 

Those 2 values are always the same when we have tested.

Link to comment
Share on other sites

Great, a CodePen will help a ton. 

 

Also: 

  1. Do you have any padding or margin on the <body> or <html>? 
  2. If you remove ScrollSmoother from the equation, does the documentElement/body.scrollHeight change at all? 
  3. If you remove ScrollSmoother from the equation and you scroll to the .scrollHeight value mentioned above, is that the very end? 
  • Like 1
Link to comment
Share on other sites

Hi.

 

In answer to your questions.

 

1. No

2. No

3. How can I do this please? I have run a setInterval function logging out ->

 

window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop

But when I scroll to the end the value is significantly less than  document.documentElement.scrollHeight or document.body.scrollHeight, but not sure if I am comparing the correct things here.

 

 

Some other observations:

 

I can replicate the issue in my browser if I 'toggle device toolbar' i.e. inspect element and click on the mobile devices icon so that the touch screen mode is simulated.

 

But as soon as I click anywhere on the page (at which touch-action: pan-x; is removed from body) and then try to scroll again, I am able to scroll to the appropriate position on the page.

 

Link to comment
Share on other sites

Do you have ignoreMobileResize: true set? And is the problem only occurring in mobile browsers that have an address bar that is showing/hiding? If you call ScrollTrigger.refresh() somewhat regularly on the page (the only thing that matters is that it gets called AFTER your viewport resizes), does that resolve things? 

  • Like 1
Link to comment
Share on other sites

Here is my initiation:

 

var smoother = ScrollSmoother.create({
  smooth: 4,
  effects: true,           
  normalizeScroll: true,   
  ignoreMobileResize: true 
})

This problem is happening in browsers in which the address bar is always visible.

 

Tried running ScrollTrigger.refresh() on a 1 second interval and that didn't help.

 

It's going to take me a while to get a codepen setup I think, this issue only exists on one page on our website:

 

I've tested it isn't related to the length of the page, I've removed all other JS unique to the problem page, this doesn't make any difference, and even removed individual sections from the problem page to see if they are causing the issue, in this case the gap at the bottom of the page between the end scroll position and the end of the page just gets smaller and smaller as more sections are removed.

 

I've tried removing all the CSS from the problem page also and this doesn't help either, still unable to pinpoint where the issue is coming from.

Link to comment
Share on other sites

If you REMOVE the ignoreMobileResize: true part, does that have any effect? What about removing normalizeScroll: true

 

How about if you grab the result of ScrollTrigger.maxScroll(window) both with ScrollSmoother enabled and disabled - are they the same? What if you take that number and scroll there WITHOUT ScrollSmoother enabled, like window.scrollTo(0, YOUR_NUMBER) - is that at the very bottom? 

  • Like 1
Link to comment
Share on other sites

Removing normalizeScroll: true seems to fix the problem. However it breaks some scrollTriggers and Pins seem to go out of whack.

 

No difference when removing ignoreMobileResize: true

 

ScrollTrigger.maxScroll(window) is the same with ScrollSmoother enabled/disabled.

 

window.scrollTo(0, VALUE) does NOT go to the end of the page

Link to comment
Share on other sites

Okay, so the maxScroll() isn't actually returning the maximum scroll in your case. Interesting. Can you figure out how to determine the REAL maximum scroll? Currently the calculation is: 

let max = (document.documentElement.scrollHeight || document.body.scrollHeight) - (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight)

Perhaps you could tweak that to see what's more accurate in your case. 

  • Like 2
Link to comment
Share on other sites

The behaviour is very strange, I get different results which seem random.

 

I've just logged out each of the above and they are as follows:

 

ScrollTrigger.maxScroll(window) = 11151

document.documentElement.scrollHeight = 12578
(document.body.scrollHeight) - (window.innerHeight) = 11151
document.documentElement.clientHeight = 1166
document.body.clientHeight = 12578

 

Link to comment
Share on other sites

The strange thing is that - 

 

window.scrollTo(0, 11120) seems to be the bottom of the page.

Link to comment
Share on other sites

I think I have found a workaround, we have a deadline soon so need to move fast on this, so we are just looking for a solution, I can then help after our deadline to try find the cause of this bug.

 

If I add smoothTouch: 0.1 it seems to be a workaround.

Can we use a smaller number than 0.1 because we prefer no change on touch screen devices?

  • Like 1
Link to comment
Share on other sites

As far as I'm aware, you can - yes, that's 0.1 seconds but you could say 0.01

  • Like 1
Link to comment
Share on other sites

Yeah, it can be very small. @JoeH is there any way you could send over a minimal demo? I'd REALLY like to see what's going on there. Even if you need to send it via DM, that's fine. 

Link to comment
Share on other sites

13 hours ago, GreenSock said:

Yeah, it can be very small. @JoeH is there any way you could send over a minimal demo? I'd REALLY like to see what's going on there. Even if you need to send it via DM, that's fine. 

 

Yes no problem, I'll set it up this weekend.

  • Thanks 1
Link to comment
Share on other sites

I have the EXACT SAME issue. Did you guys find some solution. I have tried to replicate it in other projects. The projects in which gsap is being used produce this error whereas others don't. 

 

Please assist :)

Link to comment
Share on other sites

 OMG!!! I just found the problem and solved it. In my landing page, there were some pictures that didn't have FIXED HEIGHT and ScrollSmoother seemed to forget that the page had those images. I fixed the height of images and now it's working perfectly fine. 😎

  • Like 4
Link to comment
Share on other sites

  • 2 weeks later...

First time posting here so forgive me if I'm doing something wrong!

 

We're experiencing the exact same issue and we made the exact same measurement of @JoeH with basically the same results:

 

On 4/4/2022 at 6:40 AM, GreenSock said:

Great, a CodePen will help a ton. 

 

Also: 

  1. Do you have any padding or margin on the <body> or <html>? 
  2. If you remove ScrollSmoother from the equation, does the documentElement/body.scrollHeight change at all? 
  3. If you remove ScrollSmoother from the equation and you scroll to the .scrollHeight value mentioned above, is that the very end? 
  1. Nop
  2. Yup, it gets the correct height: 11112 (when scroolsmoother is in action it's missing about 2000px: 9779)
  3. Yup

Setting normalizeScroll either true or false doesn't change the end result, same with ignoreMobileResize.

Unfortunately setting smoothTouch to 0.1 or less isn't working for us. 

 

This is how we create our ScrollSmoother instance:

useEffect(() => {
    const smoothOperator = ScrollSmoother.create({
      smooth: 4, 
      effects: true, 
      wrapper: '#___gatsby',
      smoothTouch: 0.1,
    });
    smoothOperator.refresh(); // we tried both refreshing as soon as it mount the page and not refreshing at all
    console.debug('Starting ScrollSmoother');
    return () => {
      console.debug('Killing ScrollSmoother');

      smoothOperator.kill();
    };
  }, []);

 

We're working on a reprod on codepen but i'm still not able to replicate this behaviour.

Link to comment
Share on other sites

A quick update: it looks like @Saim Abbas was right!


If some image (atm we can't say for sure if all elements or only a part of them) don't have a fixed height set scrollSmoother isn't able to figure out the correct height of our page!

 

So setting height to images seems to be required to let scrollsmoother work correctly.

  • Like 2
Link to comment
Share on other sites

6 hours ago, tramedigitali said:

If some image (atm we can't say for sure if all elements or only a part of them) don't have a fixed height set scrollSmoother isn't able to figure out the correct height of our page!

 

I assume you must be dynamically loading those images in such that the window.onload isn't triggered when they finish loading, right? It sounds like you just need to call ScrollTrigger.refresh() when those are done (or set the image dimensions, as you discovered, which is better anyway because it allows the browser to not have to run layout logic again after they load). There's a "load" event listener on the window that automatically calls ScrollTrigger.refresh(), but it sounds like you must be loading things in a different way. 

 

Glad you figured it out!

Link to comment
Share on other sites

@GreenSock you are indeed right!

Gatsby's StaticImage component actually lazy load under the hood all images rendered using it, so it might impede those refresh() calls. 

This is actually a problem nowadays as many frontend frameworks (NextJS with next/image and Gatsby as well) lazy load images if using their image component. 

 

Maybe a disclaimer in ScrollSmoother docs advising user on either setting width/height or watching for load event could be useful? 

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