Jump to content
Search Community

Page jump on mobile after scrolling past scrollTrigger pinned section

kubik101 test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi Guys.

 

I have replicated my issue in CodePen but you can not see the issue unless you view it in a mobile browser without CodePen wrapping it.

 

So to show you, I have placed the same code that is in the CodePen in a html version as a visitable link.

https://kubikdesign.com.au/posts/20230610-gsap-jump-issue.html

 

The issue is: after scrolling past the scrollTrigger area the page jumps up.

 

I have also created a screen recording on/of my mobile showing and explaining the issue (ensure sound is on).

https://kubikdesign.com.au/posts/20230610-gsap-jump-issue.mp4

 

Thanks guys.

😃

See the Pen yLQNLZx by kubik101 (@kubik101) on CodePen

Link to comment
Share on other sites

Was playing/interacting with the html version on my phone.

See my observations here (ensure sound is on): https://kubikdesign.com.au/posts/20230610-gsap-jump-issue-02.mp4

 

Just a theory:

I think the issue is because on mobile the browsers address bar and toolbar disappear/re-appear when you scroll down (disappear) and when you scroll up (re-appear) and as a result something funky is happening in gsap's calculations.

Link to comment
Share on other sites

Hi Guys.

 

I have been doing more investigation and the issue is definitely related to the browsers address bar and toolbar disappearing/re-appearing.

 

- - - 

 

To prove this I measured how much the page is jumping and compared that value to the difference in the viewable height of the browser.
This visible difference is seen in the image I have created which shows in "RED" the 350(^) extra pixels when toolbar and address bars are hidden (I will refer to the 350px(^) value further down).

 

(^) please note screenshot is done on retina screen so divide by 2 for classic pixels.

 

- - - 

 

I also found that the value of the "end:" in the gsap.timeline affects how much the page jumps.

 

In my original code pen and html file you will notice I have end: '+=500%', (full timeline code below)

 

let tl = gsap.timeline({
    scrollTrigger: {
        trigger: section,
        pin: true,
        start: 'top top',
        end: '+=500%',
        scrub: 0,
        anticipatePin: 1,
        invalidateOnRefresh: true,
    },
})

 

So in this case the page jump is big because the jump is equal to 5 * 350px(^) which equals 1750px(^)

 

I then tested this theory with end: '+=100%', and end: '+=200%', and found that yes the jump was equal to the amount of % eg:

end: '+=100%', = 1 * 350px(^) which equals 350px(^)
end: '+=200%', = 2 * 350px(^) which equals 700px(^)

 

- - - 


This is now presenting as a bug unless there is a setting or solution I have overlooked??


- - - 

 

Side thought: Is GSAP using DVH as a unit of measure Dynamic Viewport Height which could be contributing to this?

screens.jpg

Link to comment
Share on other sites

Hi @kubik101 thanks for all the research! Would normalize: true work? I did a quick test and it seems to be the case. From the docs https://greensock.com/docs/v3/Plugins/ScrollTrigger

 

Forces scrolling to be done on the JavaScript thread, ensuring screen updates are synchronized and the address bar doesn't show/hide on [most] mobile devices.

 
It could also help if the height would be a fixed value. I'm not completely sure, but ScrollTrigger watches for resize events and will update function based values, so you could remove your function based values or get a value that doesn't change when the address bars show and hide. Again I'm not sure, but maybe offsetHeight gets recalculated when the browser bars are removed?
 
Just FYI if you're viewing a pen that you've created and click on the change view icon, you can open "Debug mode" which allows you to few your pen without any of the Codepen interface. This is limited for none pro users, but can come in handy from time to time. Hope it helps and happy tweening! 
 

See the Pen eYQNJYX?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

Link to comment
Share on other sites

Hi mvaneijgen.

 

I tried putting normalise on and it did not help the issue, see here:

https://kubikdesign.com.au/posts/20230610-gsap-jump-issue-normalize.html

 

Also your comment here:

Quote

It could also help if the height would be a fixed value. I'm not completely sure, but ScrollTrigger watches for resize events and will update function based values, so you could remove your function based values or get a value that doesn't change when the address bars show and hide. Again I'm not sure, but maybe offsetHeight gets recalculated when the browser bars are removed?

 

If you are referring to the .gsap--section (which i hope you are), that is set to a minimum height of 100vh, which does not get affected by resize events.

 

My use of offsetHeight is only to calculate Y positions and height of the scrolling black divs etc, nothing to do with the height of the pinned section.

 

Issue is still unresolved, does (you) or anyone have any other possible solutions?

Link to comment
Share on other sites

9 hours ago, kubik101 said:

This is now presenting as a bug unless there is a setting or solution I have overlooked??

Nope, it's not actually a bug - let me explain...

 

When the browser shows/hides the address bar, it fundamentally changes the height of the viewport, so anything you've set up in your CSS to use vh, for example, will suddenly resize! So if you've got 10 sections that are 100vh and then the viewport changes by 350 pixels, your entire web page will change by 3500px in overall height! That of course will also change where all the start/end scroll positions are for each of the trigger points. 

 

For example, let's say your 4th 100vh section is 2000px from the bottom of the viewport initially (thus it would take 2000px of scroll to hit it)...but then the address bar hides which changes the viewport height by 350px. Well now all your 100vh sections are 350px taller, thus it will take 2700px of scroll to get there. This affects all of the ScrollTriggers that aren't in the viewport initially - they all must recalculate (which is what happens on a ScrollTrigger.refresh() which happens automatically by default when you stop scrolling after that resize). That's what causes the "jump". It's logically necessary for that to happen if you want to keep all the trigger positions perfectly accurate. 

 

However, if you don't mind the start/end positions staying where they are (thus technically they're not accurate according to when those trigger elements enter/leave the viewport) and you'd rather prioritize preventing that jump when things recalculate, you can do this: 

ScrollTrigger.config({ ignoreMobileResize: true });

Which just tells ScrollTrigger to skip its automatic refresh() when the window resizes vertically by less than 25%. 

 

Does that help? 

 

9 hours ago, kubik101 said:

Is GSAP using DVH as a unit of measure Dynamic Viewport Height which could be contributing to this?

Definitely not. 

  • Like 2
Link to comment
Share on other sites

Hi Jack.

 

Thank you for your reply.

 

- - - 

 

May I firstly clarify something so that we are on the same page here.

 

Let's forget about GSAP and scroll trigger for a moment and focus on the units vh and dvh.

 

VH on its own will not affect and shift the height of the page as you scroll down on mobile.
- https://kubikdesign.com.au/posts/gsap/03-no-gsap-100vh.html

 

DVH on its own will affect and shift the height of the page at the exact moment the toolbar and address bar dis/and re-appear.
- https://kubikdesign.com.au/posts/gsap/04-no-gsap-100dvh.html

 

^ Do we agree on this?

 

- - - 

 

Now let's talk about when GSAP and scroll trigger are involved.

 

Looks like regardless of height, when pinning scrolltrigger places a pin-spacer with inset: 0; and a height and padding based on the height of the screen multiplied with your end: eg. end: '+=500%'.

 

New 400px height example: https://kubikdesign.com.au/posts/gsap/01-original-400px.html
Original 100vh example: https://kubikdesign.com.au/posts/gsap/01-original-100vh.html

 

Both the 400px high and 100vh versions jump, because the pin-spacer is being recalculated on window resize being triggered by the browsers automatic appear/disappearing of toolbars and address bar when scrolling.

 

So your suggestion to use "ignoreMobileResize: true;" is the solution (thank you!) but is unrelated to using 100vh on the pinned section - agreed?
- Solution applied (no jump now, yay!): https://kubikdesign.com.au/posts/gsap/02-original-100vh-ignore-resize.html

 

- - -

 

Now I am curious how to go about pinning a section with a height smaller then the screen height and have the next section (purple) immediately after it whilst the blue gsap section is pinned.
(CodePen updated to 200px high section and end: '+=100%')

 

Currently the pin-spacer's height gets set to the height of the screen showing the background color, pushing the next purple section out of view.

 

** you may say to try pinSpacing: false; putting this in means the purple and other sections scroll behind whilst the blue is pinned.

 

So how do we solve this scenario when a pinned section is smaller than screen height and we want the next section to be immediately after the pinned section?

 

Link to comment
Share on other sites

58 minutes ago, kubik101 said:

Let's forget about GSAP and scroll trigger for a moment and focus on the units vh and dvh.

 

VH on its own will not affect and shift the height of the page as you scroll down on mobile.
- https://kubikdesign.com.au/posts/gsap/03-no-gsap-100vh.html

 

DVH on its own will affect and shift the height of the page at the exact moment the toolbar and address bar dis/and re-appear.
- https://kubikdesign.com.au/posts/gsap/04-no-gsap-100dvh.html

 

^ Do we agree on this?

On most mobile devices, that's true. If you check window.innerHeight it does change, though. That's the fundamental problem here. But this thread prompted an idea to rework some of the logic internally so that it temporarily swaps in an invisible <div> with its height set to 100vh to convert that into px for the purposes of calculating the scroll offsets (start/end values), and only on refresh() to maximize performance. It does seem to work - here's a beta file with that change in place: 

https://assets.codepen.io/16327/ScrollTrigger.min.js (you may need to clear your cache)

 

Does that work more like you wanted? 

 

2 hours ago, kubik101 said:

So how do we solve this scenario when a pinned section is smaller than screen height and we want the next section to be immediately after the pinned section?

You can just wrap it in a container and pin that instead: 

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

 

Is that what you're looking for? 

 

Just make sure that if you add other ScrollTriggers that use triggers that are inside that container, you define it as the pinnedContainer so that ScrollTriggers knows to compensate accordingly. 

  • Like 2
Link to comment
Share on other sites

Hi Jack.

 

I am really appreciating your help.

 

- - - 

You are correct, window.innerHeight does change height as the toolbars disappear/re-appear.

 

But just to be clear, elements with a css value of 100vh will not change their height at any point (that's what 100dvh is for).
100vh will take on the height of the window as if the toolbars and address bars have disappeared and I would expected gsap/scrollTrigger to behave the same out of the box.

 

Which I think your beta fix is now pretty much doing.

 

- - - 

 

Wow! Thank you for being so proactive and supplying this beta file, I have put it in my example and yes it behaves as expected.
- https://kubikdesign.com.au/posts/gsap/00-original-100vh-beta.html

 

- - - 

 

And thank you so much for answering my secondary question, much appreciated again..!!

 

- - - 

 

Thank you once again Jack, I am pleased this lead to an improvement to an already amazing library!

 

😃

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

For those looking for the solution.

 

This will fix your issue, but looks like it won't be necessary in this scenario once Jack's beta code becomes part of the main build (correct me if I am wrong @GreenSock.

 

ScrollTrigger.config({ ignoreMobileResize: true });
  • 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...