Closed Bug 1530253 Opened 5 years ago Closed 2 years ago

Support re-snapping for scroll snap

Categories

(Core :: Layout: Scrolling and Overflow, enhancement, P3)

64 Branch
enhancement

Tracking

()

RESOLVED FIXED
104 Branch
Tracking Status
relnote-firefox --- 104+
firefox104 --- fixed

People

(Reporter: hiro, Assigned: hiro)

References

(Depends on 1 open bug, Blocks 3 open bugs, )

Details

(Whiteboard: [layout:backlog], [wptsync upstream])

Attachments

(10 files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

The spec clearly says;

If the content or layout of the document changes (e.g. content is added, moved, deleted, resized) such that the content of a snapport changes, the UA must re-evaluate the resulting scroll position, and re-snap if required. If the scroll container was snapped before the content change and that same snap position still exists (e.g. its associated element was not deleted), the scroll container must be re-snapped to that same snap position after the content change.

But as far as I can tell Chrome doesn't re-snap yet, so I am going to defer this feature for now.

Whiteboard: [layout:backlog]

Emilio has already raised a spec issue that is that whether re-snap is prior than scroll-anchoring.
https://github.com/w3c/csswg-drafts/issues/4830

The spec seems to be settled as of recently based on the issue above.

Both Chrome and Safari have been supporting this part of the spec for quite some time now. Since the issue with scroll-anchoring has been resolved in the spec, it would be great to see this come to Firefox as well.

That would remove the need to manually (and imperfectly) scroll back to the snapping point after detecting a layout change (or not doing it at all and exposing the user to undesirable situations).

How difficult is this to implement, Hiro? I think this would greatly simplify our manual scroll snapping inside devtools.

Flags: needinfo?(hikezoe.birchill)

In most cases where re-snapping should happen the implementation shouldn't be hard, we can just re-evaluate snap points when it's necessary (e.g. the scrollport size is changed). One case it's unclear to me is that if there's an on-going async scrolling, I'd suppose no re-snap should happen during the async scrolling, but I am not sure, I'd hope there's at least one wpt for the case.

Flags: needinfo?(hikezoe.birchill)

Note that we have a plan to do this in this H2, FWIW.

See Also: → 1768746
Assignee: nobody → hikezoe.birchill
Status: NEW → ASSIGNED
Depends on: 1772272

I am going to summarize about re-snapping feature, what the spec definition is, what we need to do is.

  • We need to maintain the snap target(s) where we snapped on the last scroll
    operation
  • It's possible that there are multiple snap targets at the same position
  • It's also possible that the last snap point is associated with two different
    snap targets, for example, the point on X Axis is associated to a
    scroll-snap-align: none start element, on Y Axis it's associated to a
    scroll-snap-align: start none element
  • In the above case if snapping to the combination point (x, y) results both
    elements are outside of the scrollport, we need to choose a snap point on
    either X or Y axis, then re-evaluate the nearest snap point from there,
    there's a wpt for this case
  • If one of the last snapped targets has focused when re-snapping, we need to
    snap to the focused one
  • The spec doesn't define priories if there's no focused element among the last
    snapped targets so that we can choose an arbitrary re-snap point
  • Re-snapping needs to supercede scroll anchoring,
  • It's possible that snapping happens in APZ, thus we need to inform the last
    snapped targets done by APZ to the main-thread
  • There are also possibilities that an async scroll operation with snap points
    is triggered on the main-thread, e.g. async Element.scrollBy calls, thus
    we need to inform the snap points calculated on the main-thread into APZ as well

I am going to defer the last two bullet points into one or two follow-up bugs.

There are some call sites of ScrollTo involving will a GetSnapPointForDestination
call. For re-snapping, we need to inform not only the snap point but also the
snap target id(s). To do it, in subsequent patches in this commit series, we will
change only ScrollToWithOrigin arguments rather than both ScrollTo and
ScrollToWithOrigin.

Depends on D148857

The snap targt ids will be the last snap target ids we use for re-snapping.

Depends on D148859

The basic machinery to trigger re-snap is same as what scroll anchoring does,
queueing a triggering request and flush the queued requests after reflows
finished.

One caveat is that when the last scroll operation snapped to a point, we need to
clobber scroll anchoring.

Depends on D148862

Attachment #9280571 - Attachment description: Bug 1530253 - Assign an id to each scroll snap target element for tracking the last snapped element. r?botond → Bug 1530253 - Assign an id to each scroll snap target for tracking the last snapped element. r?botond!,emilio!
Attachment #9280576 - Attachment description: Bug 1530253 - Store the last snap target ids in the case of instant scroll oparations on the main-thread. r?botond → Bug 1530253 - Store the last snap target ids in the case of instant scroll oparations on the main-thread. r?botond!,emilio!
Blocks: 1774537

(In reply to Hiroyuki Ikezoe (:hiro) from comment #8)

  • It's possible that snapping happens in APZ, thus we need to inform the last
    snapped targets done by APZ to the main-thread
  • There are also possibilities that an async scroll operation with snap points
    is triggered on the main-thread, e.g. async Element.scrollBy calls, thus
    we need to inform the snap points calculated on the main-thread into APZ as well

I am going to defer the last two bullet points into one or two follow-up bugs.

Filed bug 1774537 for these two.

Blocks: 1776624
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/34670 for changes under testing/web-platform/tests
Whiteboard: [layout:backlog] → [layout:backlog], [wptsync upstream]
Blocks: 1777652
Upstream PR merged by moz-wptsync-bot

This change broke my CSS scroll snap user styles for Twitter’s timeline.

I currently apply the following user styles to the URL https://twitter.com/home via the Stylus browser extension:

html {
    scroll-snap-type: y proximity !important;
}

[aria-label="Timeline: Your Home Timeline"] article, [role="progressbar"] {
    scroll-snap-align: start !important;
}

[aria-label="New Tweets are available."] {
    display: none !important;
}

[aria-label="Home timeline"] > :first-child {
    position: static !important;
    scroll-snap-align: start !important;
}

I have recorded a video of the issue and posted it on YouTube: https://www.youtube.com/watch?v=6RodhbOVy90

Thanks Šime for reporting the issue. It looks like you are trying to scroll by mouse wheel or some such? It realized me that there's an issue that when a new mouse wheel started, it won't clobber the last snap target id(s) so that if new contents get added, it will snap to the original position.

I am going to address the issue in bug 1774537. If it takes too much time, we will back out patches for this bug.

Sorry for not mentioning this detail. When I try to scroll with the Spacebar key, nothing happens (the page doesn’t scroll at all), and when I try to scroll with the laptop’s trackpad (vertical two-finger swipe), I get the glitchy behavior seen in the video that I linked above.

:hiro do you think this needs a relnote for fx104?

Flags: needinfo?(hikezoe.birchill)

I was actually unsure whether this kind of changes should be noted in release notes or not, so I asked some folks, our conclusion is, given that there's a spec section about this feature, so that it's probably worth noting in the release note.

Note that bug 1312165 is somewhat relevant with this bug, which was fixed in 103 cycle, I believe it should be noted in the release note.

Flags: needinfo?(hikezoe.birchill)
Blocks: 1686571

As I wrote in comment 23 above, I use the Stylus add-on to add CSS Scroll Snap to the Twitter timeline. I’m testing in Firefox Nightly, and the new re-snapping behavior is making it impossible to view the content of tweets that are taller than my viewport.

I have recorded a video of the issue here: https://www.youtube.com/watch?v=bSJyg7DKqAc

This happens when I scroll using my laptop’s trackpad or the Space bar key.

The user styles that I add to the Twitter timeline:

html {
    scroll-snap-type: y proximity !important;
}

article {
    scroll-snap-align: start !important;
    scroll-margin: 53px !important;
}

As you can see, the code couldn’t be simpler. I apply proximity snapping to the page and then snap to the start of the tweets in the timeline (which are <article> elements). The scroll margin is there because of Twitter’s sticky header.

I am not sure why Firefox is re-snapping so aggressively (as my linked video shows). Maybe Twitter is mutating the DOM too often (due to the virtual scroller). If possible, I would like to be able to *disable re-snapping. I prefer the behavior in Firefox release, which doesn’t have re-snapping yet.

Šime, I assume you tested in the 2022-07-16 nightly, which is the first to include the fix for bug 1774537?

If so, could you kindly file comment 28 as a new bug, and mark it as "regressed by" this one?

Regressions: 1779909
Depends on: 1780701
No longer depends on: 1780701

Here is a description about re-snapping for the rel note.

"Firefox now supports re-snapping, it tries to keep the last snap position after any content/layout changes."

Regressions: 1788029
Regressions: 1791606
Duplicate of this bug: 1124324
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: