During the development of my web app, I encountered a strange issue that is subtle and challenging to debug. This issue is particularly troublesome in terms of user experience and occurs exclusively on mobile browsers.
My website is composed of several views, with each view containing multiple "snaps" - full display sections that users can swipe up and down, similar to TikTok or Instagram Reels.
To implement this, I am using pure HTML and CSS:
html {
scroll-snap-type: y mandatory;
overscroll-behavior-y: none;
}
.section {
position: relative;
max-width: 100vw;
max-height: 100vh !important;
scroll-snap-align: start;
overflow: hidden;
}
<div class="view">
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
</div>
<div class="view"></div>
<div class="view">
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
</div>
Only one view is visible at a time. I use Vue.js, so the DOM is updated dynamically, and there's only one .view element present. However, I encountered the same issue while using pure JavaScript and calling .show()/.hide() to manage displaying the desired view.
The problem is as follows:
- The user scrolls (using snaps) to a certain section of the current view.
- The view changes. The new view can, but does not necessarily have to, contain snap sections.
- The user lands at the same position they exited at in step 1. So, if they were at the third section, and the new view also has sections, the page will be positioned at the third one.
This behavior occurs even if there is a view without any scrolling in between. For example, the user is at view 1, section 3, goes to view 2 without sections, and then goes to view 3 with sections, and is placed at section 3 again.
Another interesting factor is that if the new view has fewer sections than the number of the section the user was at last time, they will start at the top.
I imagine this is somehow a desired behavior meant to provide a consistent UX for navigating through a website.
However, I need a solution to start at the top for each new view that is displayed to the user.
I would greatly appreciate any help in finding a way to deal with this issue.
EDIT
Several answers mention scrollTo function. It does not work. No matter how it's called, it gets overwritten by the snap position.
I tried recreating it on Chrome, as I am not able to test it on iOS Safari, and suspect that it has to do with you not having any sections in your 2nd container. As scroll-snap-align is set on the sections and not the containers it searches for the next scroll point to align itself to which is the first section in the 3rd container.