Skip to content

[css-scroll-snap-1] Avoid page scrolling skipping past snappable items #10914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
flackr opened this issue Sep 18, 2024 · 6 comments
Open

[css-scroll-snap-1] Avoid page scrolling skipping past snappable items #10914

flackr opened this issue Sep 18, 2024 · 6 comments

Comments

@flackr
Copy link
Contributor

flackr commented Sep 18, 2024

This originally came up from @johannesodland as a potential issue with scroll-buttons in #10722 (comment) however it's a pre-existing generic issue with scroll-snap, so filing it separately.

When a user pages down, usually by pressing the page-down key, they expect to scroll no further than one page if that is a valid scroll location. However, some browsers can select the next snap point as the target resulting in a scroll of more than a scrollport in length.

E.g. if you have a scrollport height of 1000px, most browsers will try to scroll by 850px. If however the nearest snappable element has a snap alignment that is further, then it can be selected, resulting in scrolls even greater than 1000px and an experience where content has been skipped over - even when that content itself defined a valid snap area. We should fix this so that it's easy to make an experience where

Codepen demo using page-down key: https://codepen.io/flackr/pen/abgeOKY
Original demo from @johannesodland using scrollTo api: https://codepen.io/johannesodland/pen/WNqmoYy

@flackr
Copy link
Contributor Author

flackr commented Sep 18, 2024

Naively for built-in interactions, the UA could do something like select a snap area which scrolls no further than 100% of the scrollport if possible, though I wonder if there's some way we could make this work for programmatic scrolls as well as in the scrollTo example?

E.g. we could say that for any scrolls less than or equal to 1 scrollport, we try to select a snap area which keeps the scroll less than that distance. I say "try" because developers can position snap areas arbitrarily far apart and we should make some progress in the requested scrolling direction.

@flackr
Copy link
Contributor Author

flackr commented Sep 18, 2024

Alternately a more generic option could be to snap in a way that scrolls no more than the requested distance if possible. This would ensure that page-down never scrolls more than 85% unless that is necessary to go to the next snap area.

@css-meeting-bot
Copy link
Member

css-meeting-bot commented Sep 27, 2024

The CSS Working Group just discussed [css-scroll-snap-1] Avoid page scrolling skipping past snappable items, and agreed to the following:

  • RESOLVED: pageUp/pageDown type operations should never scroll by more than a page, unless that's the only valid snap area
  • ACTION: flackr to sketch out a scroll-by-page API
The full IRC log of that discussion <fantasai> flackr: context of scroll buttons , but pre-existing issue with snapping
<fantasai> flackr: currently if you pgae down, the browser can select a snap area that is more than one page away
<fantasai> flackr: even though there's a possible snap area that's not that far away
<fantasai> flackr: I propose putting wording in the spec that, at least for explicit actions like page down, find a snap area that is less than one page away
<fantasai> flackr: so that you don't skip over content
<fantasai> flackr: then I had a further open question of whether we need to solve this for scrolling APIs
<fantasai> flackr: original issue was calling .scrollTo
<fantasai> flackr: to mimic same behavior
<dholbert> fantasai: I think yes, page-up page-down should scroll <= viewport
<dholbert> fantasai: might be exactly equal, but could be <=
<dholbert> fantasai: for programmatic API, those are supposed to [...]
<Rossen6> ack fantasai
<dholbert> fantasai: ...have the same behavior as a person scrolling
<dholbert> fantasai: if scroll-snap is going to interfere with a person scrolling, then programmatic aPI should get that same interference
<dholbert> flackr: if I make a page-down button, as a web developer, and add an event listener that calls scrollTo(currentPos + 85% of scrollport)
<dholbert> flackr: the same problem as pressing pagedown on keyboard exists, that browser could select something further away
<dholbert> flackr: should we try to scroll less?
<dholbert> fantasai: round-down version?
<dholbert> flackr: most expressive version is to say "don't want to scroll more than 1 page"
<dholbert> fantasai: ...
<dholbert> flackr: that's scrollIntoView
<dholbert> flackr: this is for APIs where you specify how far you want to scroll, or a position
<dholbert> fantasai: do we want to add a scrollByPages API?
<dholbert> flackr: that would be reasonable
<dholbert> fantasai: or do we give a "bias-towards" parameter?
<dholbert> fantasai: which of those would make more sense
<dholbert> flackr: I feel like we'd be more likely to do what the dev expects, if the API was specifically "scroll by a page"
<dholbert> fantasai: I guess then we have 2 resolutions?
<dholbert> fantasai: (1) pageUp/pageDown type operations should never scroll by more than a page, unless that's the only valid snap area
<dholbert> PROPOSED RESOLUTION: pageUp/pageDown type operations should never scroll by more than a page, unless that's the only valid snap area
<dholbert> RESOLVED: pageUp/pageDown type operations should never scroll by more than a page, unless that's the only valid snap area
<dholbert> fantasai: (2) we want to add some kind of scroll-by-page type API, to be sketched out by flackr
<dholbert> flackr: I can sketch that out
<dholbert> Rossen6: no need to resolve on that now
<fantasai> ACTION: flackr to sketch out a scroll-by-page API
<dholbert> FWIW there is a scrollByPages API in Firefox, non-standard: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollByPages

@flackr
Copy link
Contributor Author

flackr commented Sep 27, 2024

From @dholbert:

FWIW there is a scrollByPages API in Firefox, non-standard: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollByPages

@dholbert
Copy link
Member

From @dholbert:

FWIW there is a scrollByPages API in Firefox, non-standard: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollByPages

Indeed; I'm pretty sure this is how we implement the Space/PageDown and PageUp scrolling actions under-the-hood (as calls to scrollByPages(1) and scrollByPages(-1), from Firefox's frontend JS). But the JS API is also exposed to the web, too, for historical reasons I guess.

The scrollByPages() implementation is here if anyone's curious to see it. That function calls a generic C++ ScrollBy() function that's shared by a bunch of programmatic scrolling APIs, and the most relevant piece there for scrollByPages is the GetPageScrollAmount() function, which defines what it means to scroll by a page.

flackr added a commit to flackr/csswg-drafts that referenced this issue Dec 13, 2024
As per w3c#10914 when selecting a snap point as a result of a scroll by page operation we should always select a snap position that is less than a page away if one exists.
tabatkins pushed a commit that referenced this issue Jan 22, 2025
)

As per #10914 when selecting a snap point as a result of a scroll by page operation we should always select a snap position that is less than a page away if one exists.
@argyleink
Copy link
Contributor

could we make snapping more conservative and choose the nearer of the points instead of the further?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Friday morning
Development

No branches or pull requests

5 participants