withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.49k stars 2.46k forks source link

`ViewTransitions` router causes the browser address bar to reappear every time scrolling stops on browsers that hide the address bar on scroll #12285

Open Trombach opened 1 week ago

Trombach commented 1 week ago

Astro Info

Astro                    v4.16.7
Node                     v18.20.3
System                   Linux (x64)
Package Manager          unknown
Output                   static
Adapter                  none
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

Chrome (maybe others too)

Describe the Bug

When adding the ViewTransitions component, Astro attaches a scrollend event to the dom which causes issues on touchscreen devices, for which browsers often hide the address bar when the user scrolls down. This call to replaceState seems to be the issue, as it forces the browser to show the hidden address bar. This recording demonstrates the problem. The effect is not very noticable in this minimal example, but it becomes quite problematic if scroll-based animations are used: content shifts visibly when scrolling is stopped.

I have confirmed that removing the call to replaceState in the scrollend handler (locally in node_modules) fixes this issue, however, I'm not sure what other effects this might have. I guess it would break the scroll position restoration on navigation? I would be more than happy to submit a PR to fix this issue, but I'm not quite sure how to tackle it.

What's the expected result?

When scrolling ends, browser behaviour should be consistent with not using the ViewTransitions polyfill. The address bar should remain hidden.

Link to Minimal Reproducible Example

https://stackblitz.com/~/github.com/Trombach/astro-vt-scroll-bug

Participation

martrapp commented 1 week ago

The only reason for the scroll listeners is to record the last scroll position before someone presses the browser back button. By the time we realize that there as a back navigation, the browser already switched history to the that page and we are not able anymore to store the current scroll position in the entry of the page we just left.

We could come up with an alternative design the stores the historic scroll position outside of the browsers history but that would be a larger refactoring.

But maybe others have some simpler ideas?

Trombach commented 1 week ago

Thanks for the explanation @martrapp. Maybe this could use sessionStorage instead? That would feel a lot like reimplementing the history API, but maybe it's ok for this limited use case 🤔 Still a refactor though, yes