w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[css-scroll-snap-2] Should scrollsnapchanging target the currently visible element during flings #10838

Open flackr opened 1 week ago

flackr commented 1 week ago

The css-scroll-snap-2 spec says the following about scrollsnapchanging:

A scrolling operation might animate towards a particular position (e.g. scrollbar arrow clicks, arrow key presses, "behavior: smooth" programmatic scrolls) or might directly track a user’s input (e.g. touch scrolling, scrollbar dragging). In either case, the user agent chooses an eventual snap target in each axis to which the scroller will snap after the scrolling operation reaches its intended scroll position.

In the former case, the intended scroll position is the scroll animation’s target scroll offset.

In the latter case, the intended scroll position is the current scroll offset as determined by the user’s input.

For the case where the user is or was interacting and initiated a fling, Chrome determines the eventual snap target which can mean that we immediately dispatch a scrollsnapchanging event for the location the scroll will eventually land even if it will pass over the areas which would normally snap to other elements first. This was called out in the Scroll Snap Events article and is illustrated by several of the demos such as the scrollsnapchanging visualizer demo.

Note that the spec text does not seem to imply this behavior - since it says in the latter case referring to cases where it "might directly track a user's input (e.g. touch scrolling, scrollbar dragging)" that it is intended to use the current scroll offset, so it would seem that my desired outcome might match the spec but not chrome.

I think for cases where you have clicked on an anchor link and we are executing a smooth scroll to a predetermined location, using the eventual target is a better experience than flipping through all of the snap targets as they fly by (demo), however, during a scroll interaction having the tracked item switch from on screen (while the finger is down) to the eventual target offscreen after you lift your finger and start a fling feels unintuitive to me (e.g. fling in the previous demo or this ruler demo for a more obvious example where it feels unintuitive).

flackr commented 1 week ago

I think @argyleink would prefer to see a different event for this.

argyleink commented 1 week ago

yeah, the most common description among my queried community was "fly over", but the technical term is closer to "scrollSnapAxisCross" or "scrollSnapOverAxis".

I do think this is a nice addition, it's in-between the current features in terms of information, and it does open up the information that's otherwise private or hard to decipher for authors.

question: is intersection observer already built for this purpose?
intersection observer works on area intersection, while this event is oriented more towards axis intersection. but couldn't the area of the IO be created to be thin and tall, like an axis? regardless, a simple and easy to use callback for axis crossing would be nice to have.

flackr commented 1 week ago

Do you have particular use cases for which you think that the current behavior on flings is better? Or are they the ones in those demos? In my experience, I haven't seen websites or native applications where a fling predicts the destination beyond the next item. Maybe we could prototype whatever the most compelling use cases are and spot check / vote whether the current behavior or my proposed change is better or whether there are use cases for both?

argyleink commented 1 week ago

Do you have particular use cases for which you think that the current behavior on flings is better?

i think almost all of the examples are better with the current behavior, except maybe the ruler.

In my experience, I haven't seen websites or native applications where a fling predicts the destination beyond the next item.

agree, me neither. but i also don't think that makes them better, but it does mean it's more familiar. animation-timeline: view() is maybe closer to what they're using too, instead of callbacks/triggers? the ruler uses a combination of them, but does reserve the "current indicator" visual effect not scroll driven; i felt it made the UI selected item feedback stand out.

Maybe we could prototype whatever the most compelling use cases are and spot check / vote whether the current behavior or my proposed change is better or whether there are use cases for both?

you know my feelings about prototypes! they can speak 1000 words. let's do it.

there are use cases for both

i think if i used view() and specified a small animation range that matched the axis area, i could listen for animationend on the snap items and simulate getting a callback like this scrollSnapOverAxis would add. also think IO could help us too, but be more manual work to isolate the intersection.

random thoughts the unique aspects of this event is that it fires more eagerly than the other 2 events. it would also fire at the same rate as scrollsnapchanging for nearly all user interactions except a fling. it's the same as the others in that it'd be useful for scroll triggered animation, from either CSS or JS. last random thought, I wonder if folks would debounce or throttle this event because it was so eager? I feel like the current scrollsnapchanging event is modern in it's take, smarter and less wasteful, like an evolution that required "prediction" information which maybe wasn't available in older API implementations.

flackr commented 1 week ago

animation-timeline: view() is maybe closer to what they're using too

Right, this would produce the expected behavior for flings, but it would mean that clicking on an anchor link, e.g. the 5 in my demo would also slowly step through each element, delaying the feedback that you have selected the 5th page. For targeted scrolls, it makes sense that the user has an expectation about where it is going and so expects immediate feedback about the target location.

I have two main concerns about predicting the fling:

I'll prototype something up to make it easy to compare the two which I think will help with deciding on one of three outcomes:

  1. Fling momentum prediction is better, we should ensure it is spec'd.
  2. Not predicting fling momentum scrolls is better, we should change chrome
  3. Each has their use cases. We should figure out how an author should choose they want.