Jump to content
GreenSock

o1y

GSAP ScrollTrigger is causing a scroll to top on iOS 16 Safari (Nuxt)

Recommended Posts

On iOS 16 Safari with Nuxt V3 and GSAP ScrollTrigger and scroll-behavior: smooth; in my stylesheet, the page automatically scrolls back to top when scroll animation has ended. I'm absolutely not sure if this is related to GSAP Scroll Trigger or if this is an iOS 16.0 bug 🤐 I already tried latest Beta v.3.11.2, which has the same effect.

 

Screencast
On the left side you'll see an older iOS 14.x release, on the right side the latest iOS 16.0.
https://user-images.githubusercontent.com/1102712/191813194-b7d8b2d5-08e8-4c42-bfc8-18bd5440872f.mov

 

Workaround
Remove scroll-behavior: smooth; or remove scrollTrigger or use an older iOS version :)

 

Reproduction (Nuxt v3)

https://stackblitz.com/edit/github-gwd8gb?file=app.vue

  • Thanks 1
Link to comment
Share on other sites

To my knowledge, you should avoid combining ScrollTrigger and scroll-behavior: smooth. The reason is that you don't want the two fighting over what the true scroll behavior is, and when you use scroll-behavior smooth, it is handled by CSS and not accessible in the same way to GSAP.

Is there a reason you need scroll-behavior smooth?

  • Like 3
Link to comment
Share on other sites

Interesting, thanks for your support.

 

I did not know that there are issues with scroll-behavior: smooth and ScrollTrigger. I want to add a smooth scrolling effect for anchor links on my page, that's the reason for using this property. There aren't any issues when using older iOS or when I don't use Nuxt. So with a plain HTML project or in a CodePen everything seems to be working, also on iOS 16.0 and with scroll-behavior: smooth. Super weird, but maybe I have to find another approach without that css property :)

 

Link to comment
Share on other sites

Thanks for chiming in, @o1y! Yeah, @SteveS is right - scroll-behavior: smooth is sorta like setting a CSS transition but on the scroll position, so when ScrollTrigger sets the value internally (version 3.11 sets the scroll back to the top temporarily when doing a refresh() in order to work around an edge case that could cause the measurements to be off with a partially-scrolled on a page), the browser is like "NOPE! I'm not gonna comply with that...I'll stretch that out over time instead". Just like if you tried to use GSAP to animate a property that already has a CSS transition applied - the browser will totally interfere and drag every change out over time (bad for performance and also make things look like they're taking longer to complete). 

 

I just updated the preview version of the upcoming 3.11.2 release so that it temporarily forces scroll-behavior to auto while refreshing: 

https://assets.codepen.io/16327/ScrollTrigger.min.js

 

Does that resolve things for you? 

  • Thanks 1
Link to comment
Share on other sites

Hey @GreenSock, thanks so much for your explanation! The newest beta is not resolving my described issue :(

 

I was not able to find any uncompressed sources from 3.11.2, so I did some debugging with enabled scroll-behaviour:auto on latest stable 3.11.1. On every scrollEnd, ScrollTrigger performs a _softRefresh(). Maybe that's the "refresh" you described in your last post, not sure :)

 

There is a _scrollCacheFunc called for every _scroller object, which restores (?) a cached pageY offset. For some reason the cached offsets _win.pageYOffset and _docEl[_scrollTop] are 0. That's the reason why the page is scrolling back to 0. After removing the scroll-behaviour property the cached offsets are correct.

 

But yeah, it feels like there is an interference between ScrollTrigger and the browsers scroll transition (and Nuxt / Vue ?). To be honest, I was not able to understand all the code I've seen, which is why I can't really recommend a proper fix, except to remove the scroll-behaviour property on my end. Maybe it's a good thing to console.warn() the dev about the fact this css property can cause some weird behaviour?

 

Link to comment
Share on other sites

I sure appreciate your efforts here, @o1y! That's awesome that you went through the [minified] source code to track that down.

 

I was a little confused by this comment: 

On 9/24/2022 at 8:49 AM, o1y said:

I did some debugging with enabled scroll-behaviour:auto on latest stable 3.11.1....After removing the scroll-behaviour property the cached offsets are correct.

scroll-behavior: smooth was the problem I was mentioning. scroll-behavior: auto should be fine - was that a typo on your end or am I missing something? 

 

As long as you have scroll-behavior: auto, everything works as expected, right? 

 

And are you absolutely positive that you used the latest beta file and you cleared your cache so that you're not using an old version? https://assets.codepen.io/16327/ScrollTrigger.min.js

Link to comment
Share on other sites

Hey @GreenSock!

 

Sorry for confusing you, it definitely was a typo on my end.

 

Good news: the bug is gone! No more scrolling to top with enabled scroll-behavior:smooth and your latest beta, yay. Probably I used the wrong beta last time, oops.

 

Thanks so much for your time & 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.
×