w3c / csswg-drafts

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

[css-om-view] Should overscroll ("rubber-banding") be observable? #4011

Open smfr opened 5 years ago

smfr commented 5 years ago

https://www.w3.org/TR/cssom-view-1/#scrolling-events doesn't say anything about whether a UA should fire scroll events when the user triggers overscroll behavior (https://drafts.csswg.org/css-overscroll/) and the visual scroll offset becomes negative.

WebKit has traditionally allowed negative scrollTop/scrollLeft to be observable by web content, but many pages are obviously not prepared to handle negative values (e.g. CodeMirror's gutter contents jiggle around, Quip does weird things etc). And the UI behavior that triggers negative values is an Apple-specific one; other platforms like Android don't move the content to negative offsets, but rather show an overlapping UI affordance.

Yet some authors want to tie into overscroll behavior to implement behaviors like pull-to-refresh.

So perhaps we need a new event for overscroll interactions ("overscroll"?)

jonjohnjohnson commented 5 years ago

See also https://github.com/w3c/csswg-drafts/issues/3801

css-meeting-bot commented 5 years ago

The CSS Working Group just discussed Overscroll observability.

The full IRC log of that discussion <heycam> Topic: Overscroll observability
<heycam> github: https://github.com/w3c/csswg-drafts/issues/4011
<heycam> smfr: the issue here is whether web content should be able to observe when the user is rubber banding
<heycam> ... when you reach the scroll extent of the scroll bar, and you pull down some more
<heycam> ... on Apple platforms we have rubber banding. on Android you et some overscroll affordance
<heycam> ... on Apple platforms we continue to send scroll events, and those have negative offsets if you're at the top/left
<heycam> ... or great than max offsets at bottom/right
<heycam> ... we found that this is not very web compatible, a bit of web content doesn't expect negative offsets
<heycam> ... listening to scroll events, taking those scroll positions as input to some math
<heycam> ... CodeMirror does this, the line numbers will jiggle around in weird ways
<heycam> ... so I'm considering making the rubber banding scroll offsets clamp to 0
<heycam> ... that then implies authors canont detect when that is happneing
<heycam> ... should there be a different event that gets fired during overscrolling?
<heycam> ... I saw jonjon linked to a proposal
<heycam> ... I'd like to get feedback from other browser vendors
<bokan> q+
<heycam> smfr: common desire for authors would be to have a pull to refresh
<heycam> ... it's possible I might break that when clamping to 0
<heycam> bokan: we at Chrome are very supportive of this
<heycam> ... an overscroll event?
<smfr> https://github.com/w3c/csswg-drafts/issues/3801
<heycam> smfr: we're supportive of that. we've seen this as well, implement pull to refresh is difficult
<heycam> ... pages want to know when you're reaching the end of the scroll, maybe adding a transform to start bringing in another view
<Rossen_> q?
<Rossen_> ack bokan
<heycam> AmeliaBR: so this would mean, having a separate event -- the scroll event would never give you overscroll results, never give you negative offsets or larger than max
<heycam> ... and then this custom overscroll event would start firing instead?
<heycam> ... also means author could listen to overscroll without listening to scroll
<heycam> ... so they could handle pull to refresh even if they don't care about regular scrolling
<heycam> ... so smfr your only concern is that web apps might be currently listening to negative scroll offsets, when whta they really want is overscroll events?
<heycam> smfr: yes
<heycam> ... there is one somewhat tricky thing here which is if the user built up enough momentum when scrolling, and the scroller hits the end, it will rubber band
<heycam> ... so the overscroll events probably need to contain enough info to know the user has the finger down
<heycam> myles_: an additional benefit, a website might not care where you are in the content, but do care about overscroll
<heycam> ... distinguishing the types lets you do that
<heycam> heycam: especially since scroll events are bad for perf?
<heycam> mstange: scroll events themselves are fine because they fire async
<heycam> ... wheel events are bad for perf, but that's only on desktop
<heycam> smfr: wheel events and touch events are input to scrolling, scroll events are reactive to scroll
<heycam> mstange: I support the addition of scroll events, having a distinction is good
<heycam> smfr: the CSSOM View spec is the one that talks about scroll events
<bkardell_> +1
<heycam> ... would it fit into that spec?
<heycam> emilio: probably, but do you want to edit that spec? there's no editor
<heycam> smfr: not particularly
<heycam> Rossen_: you might have to
<heycam> smfr: I'd be willing to write text for this specific thing
<bkardell_> heycam: do these just send negative positions or ...?
<bradk> If the negative offsets are going away, can they have a deprecation warning in the console for a while first? So, some overlap of having both that and the new overscroll events for a while?
<bkardell_> smfr: on some platforms there is not concept of a real negative positions values here
<AmeliaBR> The WICG repo for Overscroll & Scrollend events: https://github.com/NavidZ/overscroll-scrollend-events
<bkardell_> heycam: I am kind of wondering if we should not be asking authors to do the math to figure out these things based on positions - like when does it 'indicate'
<AmeliaBR> s/WICG//
<bkardell_> heycam: maybe we should just have events when that happens
<bkardell_> smfr: the simpler thing is that we just do that, the more complex is that we give them discrete values
<heycam> bokan: I think the pull to refresh is just one case
<heycam> ... you have a carousel article, horizotnlaly scrolling and when you reach the end you do an animated transition
<heycam> ... having a predefined animation owuld be more limiting
<heycam> smfr: I think I agree
<heycam> majidvp: I just want to point out that this matches nicely with overscroll-behavior property
<heycam> ... the author will use that property to prevent chaining, or the overscroll action triggering the native overscroll behavior
<heycam> ... and declaratively you prevent the default action
<heycam> ... then you use overscroll events to customize, create the animation that responds to user input without having to add any sort of blocking events, I think that allows you to do this without being main thread bound
<heycam> smfr: that sounds good
<heycam> mstange: do we already have a spec with overscroll events with delta fields?
<smfr> https://navidz.github.io/overscroll-scrollend-events/
<heycam> majidvp: this is in incubation. proposed in WICG
<heycam> ... they are looking for feedback
<heycam> ... whether you need the deltas, or maybe just the sum of the deltas, they'd like feedback on that
<heycam> ... there's also scrollend event
<NavidZ_> It is not yet in incubation. I would love more support to move the repo under WICG. So please comment on the discourse.
<heycam> mstange: is there also a way to tell -- let's say fingers down, get into overscroll, then release
<heycam> ... and you're still in the overscroll state for a while after lifting the finger
<heycam> bokan: not sure if it's patr of the same proposal, but there was an event called scrollend when the scroll gesture finishes
<heycam> ... that would be for this case
<NavidZ_> There has been some concerns for example regarding the reversal of scroll in UAs but I think we can iterate on those and add more css attributes to control those as well
<heycam> mstange: so scroll event wouldn't be separation of scroll and overscroll
<heycam> bokan: it could come between either, but all at the end
<heycam> ... it's when the finger is lifted
<heycam> ... if you're rubber banding, the proposal here would be "you're no longer scrolling"
<heycam> smfr: there's a period where the scroll view is animating back from negative position to 0
<heycam> ... when do you fire scrollend, and do you fire overscroll events for that automatic animation
<heycam> bokan: smfr you said you found negative scroll was not web compat?
<heycam> smfr: but if you turn those into overscroll events for that settling period, that's fine
<heycam> ... but I think we may need to add data to the overscroll event to say if the finger is down
<heycam> bokan: I don't think we're set on one shape of the API, but it is important to know when the user has lifted their finger
<heycam> mstange: there are a bunch of different questions here, don't know which we need to discuss now
<heycam> ... one more quesiton. the idea is scrollTop will reflect out of range values?
<heycam> smfr: having scrollTop reflect negative values is one of the big parts that's not web compat
<heycam> ... so it would need to be clamped to zero
<heycam> mstange: in the overscroll events we'd carry the correct information, maybe the relative update since the last event and the current absolute position?
<heycam> ... you need the aboslute position e.g. to update your parallax background
<heycam> ... I've seen cases maybe int he Apple Maps app, if you open a panel on the point of interest, you can scroll in the panel, and it does something parallaxy in the header imgae
<heycam> ... it wants to know the scrollTop
<heycam> smfr: I think that's probably necessary
<heycam> ... we should start opening issues on the overscroll spec
<heycam> ... and go from there
<heycam> mstange: sounds good
<heycam> bokan: there's a WICG thread about this, please chimein
<bokan> WICG thread: https://discourse.wicg.io/t/proposal-new-events-for-overscroll-and-scrollend/3481/16
<heycam> AmeliaBR: smfr did you want a resolutoin on your original issue about the scroll events and negative offsets? or are you going to wait on resolve that until overscroll events are more clearly defined
<heycam> smfr: the CSSOM View spec currently doesn't say anything about overscroll
<heycam> ... better to leave it that way until we have the rest of the stuff in a well defined state
<heycam> Rossen_: that's a good way
<heycam> ... plus when we have the WICG repo we can filing more issues there
<heycam> mstange: if we start clamping scrollTop, do we clamp other things like
<heycam> ... like getBoundingClientRect in the middle of overscroll state
<heycam> ... we can discuss those in that other location
<heycam> -- lunch time --
brunostasse commented 2 years ago

Reposting my comment here as it is directly related to the topic.

If I may comment from a developer perspective on the effect of overscroll on JS APIs:

Scroll position during overscroll or intersection observer used to detect overscroll in Safari is currently used for a variety of features and effects: custom pull-to-refresh, growing page title, growing hero image, revealing hidden elements with transitions or triggering animations elsewhere past a certain threshold, keeping parallax effects going during overscroll and not stopping abruptly, animating text features, etc.

I have myself implemented such features, and have had to disable overscroll (with overscroll-behaviour: none) in Firefox on macOS because it wasn't detectable, which is a shame. Removing it from Safari would be likely to break a large number of websites/web apps and make all these features and effects impossible. A new dedicated "pull-to-refresh" API might help recreate some of these, but probably not all.

Safari's overscroll behaviour is a translation that is in the continuity of the scroll, so it is quite natural that it is treated as such and reflected in all scroll related APIs. I would also expect it to work in combination with the upcoming Scroll-linked Animation CSS and JS APIs. It wouldn't make sense for a scroll-based animation to stop abruptly when reaching the end of the scroll container, while the content keeps moving during overscroll.

I would argue that any visual change to elements, whether it is a translation (rubberbanding in Safari) or a transformation (stretching on Android) should be detectable and reflected in JS and CSS APIs. If an element can be moved, possibly over another one, or cut by an overflow, it needs to be known by developer code, or it might break. This is true for scroll positions, intersection observer, boundingClientRect, scroll-linked animations, etc.

Even though these behaviours vary between platforms/browsers, wouldn't it be possible to write specifications for them, so that interactions with the different APIs are defined? This would allow to have interoperability between the browsers implementing them.

Hoping that helps.