Skip to content

[css-overflow-5] Scrolling to unreachable scroll aligned marker positions #11165

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

Closed
flackr opened this issue Nov 7, 2024 · 10 comments
Closed

Comments

@flackr
Copy link
Contributor

flackr commented Nov 7, 2024

There are many common circumstances in which the scroll targets of scroll markers are in unreachable positions. For example, this occurs with any list with scroll-align: center where the targeted items are significantly smaller than the scrollport.

Demo page: https://flackr.github.io/carousel/examples/prototypes/active-marker/#unreachable
Screenshot 2024-11-07 at 10 22 15 AM

Items 1 through 3 cannot get to their scroll aligned positions. Similarly the last 3 items at the least can never reach their scroll aligned position. In #10738 I have proposed a mechanism by which explicitly scrolling to an item would result in it being active even if it is not possible to scroll to. This ensures that at least clicking on the markers would result in them being active and moving to them via keyboard would work. However, as soon as you scroll, it would jump to the aligned item.

Without adding special behavior to avoid this, we would need to decide between one of 2 behaviors, as shown in https://flackr.github.io/carousel/examples/prototypes/active-marker/#unreachable. Either,

  • We always use the normal selection behavior, starting with item 4 active, or
  • We consider being at the beginning of the scroller as having the first target active and scrolling to the end as having the last item active. This results in a significant jump in the active marker once you begin scrolling.

As mentioned in the linked issue #10738, a developer, authors can avoid these unreachable target situations by:

  • adding padding to the edges of their scrolling element, or
  • ensuring their scroll marker elements are scrollport sized, or
  • enabling infinite / cyclical scrolling as in [css-overflow] Infinite scrolling #5411

We could however think on ideas for how we might expect to be able to select the items outside of the reachable range. I've listed a few potential options with demos below:

Options:

  1. Add additional virtual scrolling (demo). Naively, we could extend the scrollable range to allow virtually scrolling between the items whose aligned positions is not reachable. This seems unintuitive and confusing.
  2. We could add additional real scrolling into the extra content as in [css-overflow][css-scroll-snap] Introduce mechanism to extend scrollable overflow area to make snap points reachable #7885. This seems like it could be confusing to do automatically as the scroll range would not match the content range, but it is an option that has come up and adding padding matches the way this is typically solved in practice.
  3. Distribute scroll proportionally (demo). This would mean that we'd map the scrollable range to the proportion of the scroll aligned layout ranges including the unreachable positions. As a result, you'd be able to reach all items, however, the active item would often be different than the visually aligned item.
  4. Distribute scroll leading up to first reachable item (demo). In this case, we find the first item that is at a positive scroll offset (and similarly the last reachable item before the end of scroll) and map the scroll before you reach the first item and after you pass the last between the remaining unreachable items. This preserves the active item matching the aligned item once you reach the first aligned item. It does degenerate a bit to the current situation if your first aligned item is very close to the start of scroll as shown in the second example.
  5. Distribute some amount of the initial and ending scroll (demo). In this case, we ensure that the amount of scroll distance we distribute is non-trivial. In the prototype, we distribute the scroll up to the first item that is more than half a scrollport away from being active. This is similar to option 3 except avoids the edge case where you can immediately jump to the aligned item. Similar to option 2 though, this means that until you reach that amount of scroll the active item does not match the visually aligned item.

I think my preference would be if we decide to do this, to adopt something similar to option 5 but with a greatly reduced range over which we traverse the unreachable markers.

@flackr
Copy link
Contributor Author

flackr commented Nov 7, 2024

Note that developers currently have all of these same problems if they build something using scroll snap and imply selection based on the snapped items. We may want to consider whether we should apply similar changes to snap point selection.

@lilles
Copy link
Member

lilles commented Nov 7, 2024

Isn't this the same as issue #7885?

@flackr
Copy link
Contributor Author

flackr commented Nov 7, 2024

Option 1 is yes. The others are different in that they're not changing the layout. I only listed it here for completeness as something that has come up as an option, and doing it automatically would be different than, but adding it as a developer option would be the same and should be discussed there.

TLDR I think the issue here is what should we do, if anything, to automatically try to improve the situation.

@tabatkins
Copy link
Member

I definitely think this is a problem to solve, but I hate all the presented options. ^_^

  1. Virtual scrolling is confusing; a portion of the scrollbar doesn't cause any motion.
  2. Real bonus scrolling is awful-looking in demos like this, where there's a large distance between the ideal center and the 0 scroll position. (Especially on my widescreen monitor, phew.)
  3. Proportional redistribution screws up the entire range. Just clearly wrong in practice, as only 8 and 9 actually register themselves when snapped.
  4. Just redistributing up to the next point has unpredictable effects, since the distance to the next exact snap point might be very small (maybe even zero). But when the distance is reasonably-sized, this does look okay, and it's correct for all of the range that is alignable.
  5. The "redistribute up to half a page" seems to also misalign the entire range; the alignable items 4-8 register as something below their actual number, while 9-13 all register as something above their actual number. Nothing is correctly aligned. But I suppose if there were even more items they'd eventually align?

So I think a more subtle take on 5 would be fine; rather than half a page, perhaps just the next alignable snap point at least some fixed predetermined distance away. We could also apply this non-linearly (a cubic ramp?) so it still spends most of its time selecting the items near the alignable point, rather than ones close to the start, looking mostly correct while still visiting all the items as you scroll.

@flackr
Copy link
Contributor Author

flackr commented Nov 8, 2024

Thanks @tabatkins. I agree, with your take on all of the options (and separated the padding option to match your list), and that I think option 5 but with a significantly reduced distance over which it spreads the edge scroll may be the best among them. I've updated the demo so that it only uses 1/8 of the scrollport size so that we can play with it and get a feel for it. I'm also happy to experiment with non-linear distribution.

As for the relation to scroll snap, I think it's probably okay that this won't align with scroll snap in the edge cases.

I think the proposed resolution here for now would be to include option 5 as part of the algorithm in #10917. I suspect if/when we did make this normative it may be allowed but not required.

@tabatkins
Copy link
Member

Yeah, 1/8 of a page feels pretty good imo.

@johannesodland
Copy link

There might not be a one-size-fits-all solution for every use case.

For example, in image galleries embedded in articles, the second option might be useful.
These galleries might take up the full width of the article and use styling or scroll-driven animations to highlight the snapped item while reducing focus on the others – for instance by adjusting opacity, filters or transforms.

In such cases it's crucial that the snapped element appears near the text column, rather than being offset to one side of the article. Adding real scrolling to ensure that the snap point is reachable would solve this use case.

@tabatkins
Copy link
Member

True, tho that's not inconsistent with option 5. We could go with 5 as the behavior, and then separately have the ability to auto-add padding to the scroll container to allow all possible snap targets to be alignable. If you turn on that second ability, it negates option 5, as there's nothing unscrollable.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-overflow-5] Scrolling to unreachable scroll aligned marker positions, and agreed to the following:

  • RESOLVED: Go with Option 5
The full IRC log of that discussion <TabAtkins> flackr: this is similar to the earlier issue. i have a demo page with some options
<TabAtkins> flackr: it feels bad when you scroll that there are certain markers you just can't reach
<TabAtkins> flackr: the best compromise to handle this, short of the developer choosing to add extra padding, is to hijack the first and last "some amount" of scrolling (arbitrarily chose 1/8 of the scrollport width), and distribute that proportionally to the items before the first reachable scroll position, and same to end
<TabAtkins> flackr: so at position 0 you'll ahve the first marker selected, then you'll quickly zoom thru the unalignable markers, and then hit the first alignable marker.
<TabAtkins> argyle: if you're using scroll snap as a selection mechanism, this'll still be frustrating, but if you're just like browsing and the dots are highlighting as you scroll, it's not too bad.
<TabAtkins> argyle: so squishing down and virtualizing the amount of scroll to hit the remaining snap points seems reasonable
<TabAtkins> astearns: how does this interact with the previous resolution?
<TabAtkins> astearns: thru a non-scroll action you've activated the second item. is the scroll position now not 0?
<TabAtkins> flackr: my proposal is this doesn't change, it's still 0. but the moment you scroll, it'll jump to the first item (via this issue's calculation)
<TabAtkins> astearns: so i've navigated to item 2, i scroll to the right, my expectation is i'll go to item 3
<TabAtkins> flackr: yes, but you'lla ctually go to item 1. same as previous issue, several items conceptually at position 0, and as soon as you do a non-targeted scroll, it does a calculation (based just on scroll state) to find the active marker
<TabAtkins> q+
<astearns> ack TabAtkins
<astearns> q+
<fantasai> TabAtkins: I do recommend rolling through the demos in flackr's page
<fantasai> TabAtkins: once you play with them and realize how bad the behaviors all are
<fantasai> TabAtkins: you realize this gives you smooth behavior as you scroll
<fantasai> TabAtkins: it's not a perfect solution, but it's the best by a long shot
<fantasai> TabAtkins: all the others are actively terrible, just a little awkward, way better than the others
<TabAtkins> argyle: at least scroll padding, there's no magic. maybe there's extra space, but everything aligns, there's no edge cases, etc
<astearns> q-
<vmpstr> q+
<TabAtkins> flackr: i fully support guidance to say ideally make all your positions reachable. but i think it woudl be extremely breaking to force extra padding to your scroller.
<TabAtkins> argyle: it is annoying to add padding; flex and grid do some weird stuff
<TabAtkins> flackr: there's a linked issue to make that easier
<astearns> ack vmpstr
<TabAtkins> vmpstr: so if the first two markers aren't reachable, as i approach 0 scroll offset but not at 0, the marker would switch to the second, then the first...?
<TabAtkins> vmpstr: why not then if i click the second marker, it would position me at an offset that would show the second marker selected?
<TabAtkins> flackr: that has interactions with other specs
<TabAtkins> TabAtkins: [explains how scroll snap makes this situation untenable]
<fantasai> TabAtkins: [example of messing with scroll-snap behavior]
<fantasai> TabAtkins: You can't be in-between items when snapping is on
<TabAtkins> flackr: unless we did some signif work with scroll-snap, i think that would be even weirder
<TabAtkins> argyle: the goal is to have the perceptual marker match the end of scrolling... are we sending snap changing events?
<TabAtkins> argyle: there's like four dots i can't rest at...
<fantasai> TabAtkins: If your thing relies on actually being able to snap to every item, you need your layout to allow for snapping to those items
<fantasai> TabAtkins: we can't do anything to make that possible other than adding padding, which would break things
<fantasai> TabAtkins: There's an unwinnable situation here, need to compromise somehow
<TabAtkins> argyle: okay i'm interacting with them, they all seem to hijack my scroll in some way, 4 is the first item that snaps...
<TabAtkins> argyle: is option 5 everyone's choice for the least evil option?
<bramus> SGTM
<TabAtkins> (yes, for me)
<TabAtkins> argyle: on mobile does it get really weird?
<TabAtkins> flackr: my proposal uses a % of the scrollport width so it scrolls with the size
<TabAtkins> s/scrolls/scales/
<TabAtkins> argyle: thanks for the demo page, this experience speaks a thousand words
<TabAtkins> argyle: so these wouldn't emit snapchanging?
<TabAtkins> flackr: right because they're not snapped
<TabAtkins> argyle: okay but they just indicate visually
<TabAtkins> argyle: still a little bad but a compromise
<TabAtkins> flackr: when we support using real elements as markers, you'll also be able to use this to get those things indicated
<TabAtkins> astearns: so are we resolving on the least-bad option?
<TabAtkins> flackr: proposed is option 5 as the best we can do without breaking content. if we come up with somethign better in the future, we can consider changing it.
<TabAtkins> flackr: this does currently live in a non-normative part of the spec; we decided active marker calculation would be non-normative until we're happy with it. seems not too hard to change if we change our minds.
<TabAtkins> astearns: so proposed resolution is option 5. objections?
<TabAtkins> RESOLVED: Go with Option 5

@argyleink
Copy link
Contributor

the mismatch between this marker visualization and actual snap state, hopefully doesnt become a confusing issue later because they arent in sync

flackr added a commit to flackr/csswg-drafts that referenced this issue Dec 3, 2024
…get positions.

This adds to the non-normative suggested algorithm for selecting the active scroll marker
the proposed compromise in w3c#11165 to ensure that scrolling from start to end scrolls
through all of the markers in that scroller.
aarongable pushed a commit to chromium/chromium that referenced this issue Dec 5, 2024
Using scroll/snap-aligned positions to determine the active
scroll-marker raises an issue where some scroll-markers can never be
selected by scrolling their associated scroll container. The CSS
working group resolved[1] to address this by distributing some portion
of the scroll range to scroll-markers whose aligned positions are
up to (or beyond at the other extremity) this allocated portion of the
scroll range.

This patch makes this change and also takes care of the case where
visually separate scroll targets have the same aligned positions
(implemented in ScrollMarkerGroupPseudoElement::ChooseLayout). The page
in column-scroll-marker-006.html is one such page and has been
adjusted.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 380066548
Change-Id: I1f67e5d3d5ffc7558661b5be54cef98b25252eb5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6058735
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1391993}
tabatkins pushed a commit that referenced this issue Dec 5, 2024
…gets (#11318)

This adds to the non-normative suggested algorithm for selecting the active scroll marker
the proposed compromise in #11165 to ensure that scrolling from start to end scrolls
through all of the markers in that scroller.
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 6, 2025
It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
aarongable pushed a commit to chromium/chromium that referenced this issue Jan 6, 2025
It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 6, 2025
It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 6, 2025
It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Jan 10, 2025
…ection edge case, a=testonly

Automatic update from web-platform-tests
[carousel] Fix reserved scroll range selection edge case

It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}

--

wpt-commits: 78fc76592219ce62d2421bd86b2f6694c433b744
wpt-pr: 49930
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jan 10, 2025
…ection edge case, a=testonly

Automatic update from web-platform-tests
[carousel] Fix reserved scroll range selection edge case

It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}

--

wpt-commits: 78fc76592219ce62d2421bd86b2f6694c433b744
wpt-pr: 49930
sadym-chromium pushed a commit to web-platform-tests/wpt that referenced this issue Jan 14, 2025
It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobes@chromium.org>
Commit-Queue: David Awogbemila <awogbemila@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1402542}
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Jan 16, 2025
…ection edge case, a=testonly

Automatic update from web-platform-tests
[carousel] Fix reserved scroll range selection edge case

It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobeschromium.org>
Commit-Queue: David Awogbemila <awogbemilachromium.org>
Cr-Commit-Position: refs/heads/main{#1402542}

--

wpt-commits: 78fc76592219ce62d2421bd86b2f6694c433b744
wpt-pr: 49930

UltraBlame original commit: b61b5e8f8b2b2e306cc6e1786ea4d50f44a419b2
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Jan 16, 2025
…ection edge case, a=testonly

Automatic update from web-platform-tests
[carousel] Fix reserved scroll range selection edge case

It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobeschromium.org>
Commit-Queue: David Awogbemila <awogbemilachromium.org>
Cr-Commit-Position: refs/heads/main{#1402542}

--

wpt-commits: 78fc76592219ce62d2421bd86b2f6694c433b744
wpt-pr: 49930

UltraBlame original commit: b61b5e8f8b2b2e306cc6e1786ea4d50f44a419b2
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Jan 16, 2025
…ection edge case, a=testonly

Automatic update from web-platform-tests
[carousel] Fix reserved scroll range selection edge case

It can happen that the scroll offset at which we want to select a
marker is within the "reserved" region (The portion of the scroll range
distributed[1]  among scroll-markers whose snap-aligned positions fall
within that range) but the scroll targets are positioned such that the
first target is beyond the reserved region. In this case we should
rely on generic selection.

[1] w3c/csswg-drafts#11165 (comment)

Bug: 383555691
Change-Id: I9243a7a0c76f287489f9db3c02c804a784dd885a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6115534
Reviewed-by: Steve Kobes <skobeschromium.org>
Commit-Queue: David Awogbemila <awogbemilachromium.org>
Cr-Commit-Position: refs/heads/main{#1402542}

--

wpt-commits: 78fc76592219ce62d2421bd86b2f6694c433b744
wpt-pr: 49930

UltraBlame original commit: b61b5e8f8b2b2e306cc6e1786ea4d50f44a419b2
@flackr flackr closed this as completed Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants