Chrome's hidden CSS scroll-snap threshold and how to change it
Asked Answered
L

4

26

I have a container:

scroll-snap-points-y: repeat(100%);
snap-type: mandatory;
snap-type: y mandatory;

And three children:

height: 100%;
scroll-snap-align: center;
scroll-snap-stop: always;

This works just as expected in Firefox, but there seems to be a threshold for snapping in Chrome. When scrolling just a small amount, Chrome will snap back to the first child, while Firefox will scroll to the next child. Only after scrolling about 30% of the child height, Chrome will snap to the next one.

This behavior can be seen in this code pen.

Is there any way to disable this hidden threshold and have Chrome scroll to the next child immediately?

Logician answered 17/6, 2019 at 10:10 Comment(8)
Wondering the same! Just found out that Chrome has a really bad scroll threshold. It's super smooth in Firefox and even Chrome on Android... But on desktop it seems broken for a CSS scroll snap implementation using height 100% or 100vhSuicidal
Ironically this seems to be the exact opposite on macOS. When using a track pad, Chrome feels smooth with a very low threshold, whereas Firefox seems to have an extremely high threshold, sometimes even scrolling down when I try to scroll up. When using a mouse, Chrome seems to have snapping disabled altogether, while Firefox simply jumps back and forth between panels without any kind of transition. macOS 10.12.6, Firefox 67.0.4, Chrome 76.0.3809.36.Ragtime
What about safari on macOS, @Siguza?Suicidal
Same as Chrome, @Ole.Ragtime
Interesting. Currently experimenting with github.com/lucafalasco/scroll-snap for a decent compromise. However, seeing that Chrome feels smooth on macOS, but not on Windows and Linux, it's not as simple as to just enable the "polyfill" when Chrome is detected...Suicidal
Bah. No dice. Will do some attempts with addEventListener on scroll events tomorrow.Suicidal
All my attempts the last few days have been for naught. I've tried various versions of "if the user has scrolled a little, and nothing happened, scroll snap for them", but it quickly becomes wonky on touch devices. I've tried going all out on the scroll-snap polyfill, but that too becomes wonky on touch devices. Currently I'm wondering if I'll just attempt to open a ticket for Chrome, and/or implement a dirty blacklist using user agents...Suicidal
There are quite a few open Chromium bugs related to scroll-snapRevanchism
R
7

Based on the Chromium Bugs discussion around scroll-snap in general, it appears that the intent is to determine momentum (difficult with a scroll, slightly easier with a swipe) but the implementation is a bit wonky.

The suggestion is to utilize scroll-snap-stop: always to override that momentum intent (which you've done). However, it also mentions that scroll-margin and scroll-padding may impact the movement from one snap point to the next.

CSS Snap Scrolling from Chrome Dev

You might also want to look at the Overscroll-behavior API in conjunction with snap-scroll.

Revanchism answered 6/8, 2019 at 17:30 Comment(0)
A
3

The threshold you describe seems to be closer to 50% with 75.0.3770.100 on (desktop) Linux.

I found that the old element would snap back if I scrolled the midpoint between two elements to just before the exact middle of the viewport, while the new element would scroll into view if I moved the midpoint to just after the exact middle of the viewport. Hence, it seems the threshold is 50%.

This behavior may be significantly related to the following:

https://cs.chromium.org/chromium/src/cc/input/scroll_snap_data.cc?q=scroll-snap+&dr=C&l=152-155:

// If snapping in one axis pushes off-screen the other snap area, this snap
// position is invalid. https://drafts.csswg.org/css-scroll-snap-1/#snap-scope
// In this case, we choose the axis whose snap area is closer, and find a
// mutual visible snap area on the other axis.

I'm not sure.

I found the above searching for snap-scroll; most of the results for this query consist of HTML files and test mocks.

The other two relevant-looking results I found were

Arm answered 10/8, 2019 at 8:40 Comment(1)
Checked on my app - and YES - it is perfect now!Suicidal
Y
2

You can temporarily remove scroll-snap-align on :hover to make it go the next/previous, I guess:

#carousel.snap > div:hover {
  scroll-snap-align:initial;
}

https://codepen.io/anon/pen/BXwYPa

Yahoo answered 3/8, 2019 at 13:11 Comment(1)
In your Codepen I just get a terrible flicker when hovering. Chrome on Windows.Burgeon
O
-1

Certain issues like this can be solved by scroll-margin or scroll-padding.

Overleap answered 31/7, 2021 at 22:27 Comment(1)
How? If you had an actual example, it might be helpful.Burgeon

© 2022 - 2024 — McMap. All rights reserved.