Skip to content

[css-scroll-snap-1] Snap area trapping behavior of non scrollable elements #4496

Closed

Description

@majido

Here is the current spec text related to an ancestor element's trapping behavior for snap areas.

A box captures snap positions if it is a scroll container or has a value other than none for scroll-snap-type. If a box’s nearest snap-position capturing ancestor on its containing block chain is a scroll container with a non-none value for scroll-snap-type, that is the box’s scroll snap container. Otherwise, the box has no scroll snap container, and its snap positions do not trigger snapping.

This allows any regular element which is not a scroll container to trap snap areas.

I tested this on latest Chrome, Safari, Firefox and as far as I can tell no engine does this. Here is a simple test page that shows this. Also I don't think we have a wpt test case for it.

Beside, one can simply achieve the same trapping behavior just by having an element with overflow auto or hidden that does not actually overflow. This works correctly across all engines.

Given that no engine implements this, and the behavior can be achieved without much problem, I suggest we drop this requirement.

I am not really sure what is the motivation behind allowing none scroll container to trap snap areas so maybe I am missing something.

Activity

  1. css-meeting-bot commented on May 6, 2020

    @css-meeting-bot
    Member

    The CSS Working Group just discussed scroll-snap.

    RESOLVED: revert the previous resolution about layout containment trapping snapping points

    The full IRC log of that discussion <fremy> Topic: scroll-snap
    <astearns> github: https://github.com//issues/4496
    <fremy> florian: a while back we resolve the layout containment traps snapping
    <fremy> florian: but it's not clear to me as to what spec should define this behavior
    <fremy> florian: I don't think that css-contain should contain all the rules in details for all the other specs
    <fremy> florian: I would rather this be added to the snapping spec, because this is where you are most likely to need this
    <fremy> florian: but in this particular case
    <fremy> florian: scroll snapping discovered a whole class of things we forgot to mention
    <florian> The content, layout, or scroll position of an element with scroll containment or any of its descendants must not affect the scroll position of any box that is not a descendant of containing box for layout containment.
    <fremy> florian: so I would like to suggest an edit
    <fremy> florian: (just typed it above)
    <fremy> florian: an example would be scroll synchronization or scroll locking
    <astearns> s/of containing/of the containing/
    <astearns> (I think)
    <fremy> florian: like if you scroll one, the other follows
    <fremy> florian: but if you contain the layout, this probably shouldn't work
    <fremy> florian: i think this should be specified further in scroll-snap
    <fremy> florian: because this slows down the progress of containment
    <fremy> florian: and I would rather not
    <astearns> ack dbaron
    <fremy> dbaron: two contains
    <fremy> dbaron: you wrote "scroll containment"
    <fremy> dbaron: did you mean to write that?
    <dbaron> s/contains/questions/
    <fremy> dbaron: is that a new type of containment?
    <fremy> florian: no, its wrong.
    <fremy> florian: I meant layout containment, good catch
    <fremy> dbaron: second question then
    <fremy> dbaron: the text seems to imply that if you use the #hash part of the url to target an element, then if it is inside something that has layout containment
    <fremy> dbaron: it shouldn't work
    <fremy> dbaron: but I don't see why
    <fremy> florian: I didn't mean to say that
    <fremy> florian: I should fix the text if that incorrectly conveys that meaning
    <fremy> fantasai: I would also argue that scroll is not layout
    <fremy> TabAtkins: but you need some layout to know what is scrollable
    <fremy> florian: but you don't need the layout for the effect
    <fremy> florian: I agree it's not strictly layout
    <fremy> florian: but you can't delay recomputing a subtree if you have these interactions
    <fremy> astearns: so if I understand your proposed text would add further requirements on layout containment
    <fremy> astearns: if we don't that means that scroll effects would be have side-effects of forcing layout
    <fremy> florian: yes, but we can remove from scroll-snapping all cases we don't like
    <fremy> florian: that said, of course, if you focus from js etc then you will have to do layout anyway
    <fremy> florian: and that seems reasonable
    <fremy> florian: this is "contain" property, not "isolate"
    <fremy> florian: I think we mostly want to limit interactions, not especially outside>inside interactions
    <fremy> TabAtkins: no
    <fremy> TabAtkins: the containment is mostly from the layout perspective, the rest of the page is still allowed to affect
    <fremy> fantasai: I think scroll and layout in general are two different things
    <fremy> fantasai: maybe we should have a "scroll" containment not bundled in layout containment
    <fremy> fantasai: this might need a bit more thought
    <fremy> florian: implementors, what's your opinion?
    <fremy> florian: is scrolling more like paint, or more like layout?
    <fremy> fantasai: well, if you have a widget with 10 elements in it
    <fremy> fantasai: and I contain their layout
    <fremy> fantasai: for perf reasons
    <fremy> fantasai: but I might still want snapping to work
    <fremy> florian: if you have mandatory scroll snapping
    <fremy> florian: none-of-which has scroll-snap-position
    <fremy> florian: but the last one, has one
    <fremy> florian: but is off-page
    <fremy> florian: if the scroll-snapping is required to work, then you need the layout of all the children to know where to snap
    <fremy> fantasai: but if you target it, you still do right?
    <fremy> florian: yes?
    <fremy> florian: I guess it maybe doesn't break if the elements inside don't have snap points inside
    <fremy> TabAtkins: I think this is a particular case
    <fremy> TabAtkins: but now that I think about it
    <fremy> TabAtkins: but maybe that's not the most common case, maybe we can make an exception
    <fremy> florian: then we need a test
    <fremy> astearns: are you saying we should undo the previous resolution tab?
    <fremy> TabAtkins: yes
    <fremy> astearns: heycam felt it was weird anyway last time
    <fremy> astearns: so, ok, let's resolve to revert that resolution?
    <fremy> astearns: any objection?
    <TabAtkins> Except for the case Florian brought up (of an off-screen element being the only snap point in a mandatory container), you only need to care about snaps when the element is on-screen (and you're doing layout anyway), so unless an implementor has a good reason why layout containment trapping snaps would be good for optimization, I think we should *not* trap snaps from layout containment.
    <fremy> astearns: RESOLVED: revert the previous resolution about layout containment trapping snapping points
    <fremy> ???: which resolution are we reverting?
    <fremy> astearns: (restates_
    <cbiesinger> s/???/cbiesinger/
    <fremy> cbiesinger: ok
    <fremy> florian: so we reverted and resolved in the opposite direction right?
    <fremy> astearns: yes
    <fremy> astearns: also, no engine did trap snap before
    <fremy> astearns: so we revert back to what implementations do right now, if I understand
  2. fantasai commented on Sep 16, 2020

    @fantasai
    Collaborator

    I believe the current state of this issue is Rejected No Change based on the CSSWG resolutions. Reasoning was, you might want to prevent snap areas within a container from affecting its scroll position without having side-effects on overflow.

    @majido Do you think this would be difficult to implement? Do you think there's something else we should consider?

  3. majido commented on Oct 9, 2020

    @majido
    ContributorAuthor

    FWIW when filed this issue the motivation was mostly from implementation perspective.

    From Blink perspective the most logical thing for us to do was to update snap element mappings as part of the scroll tree. Because simply adding and removing a scroll container has well-defined hooks which we use to redistribute the snap areas to new scroll containers. Basically treating snapping as a scrolling feature allows us to reuse lots of pre-existing machinery that exists for scrolling.

    If any element can capture snap areas then you need to track their add/removal (and possibly maintain a separate tree for them 🤔 ). This is not impossible but I am not sure if it the usecase justifies the implementation cost in Blink. I am no longer have the most up to date information on this feature so take my opinion with a grain of salt. /cc @flackr who may provide better guidance.

  4. css-meeting-bot commented on Dec 16, 2020

    @css-meeting-bot
    Member

    The CSS Working Group just discussed [css-scroll-snap-1] Snap area trapping behavior of non scrollable elements, and agreed to the following:

    • RESOLVED: Mark this property at-risk
    The full IRC log of that discussion <dael> Topic: [css-scroll-snap-1] Snap area trapping behavior of non scrollable elements
    <dael> github: https://github.com//issues/4496
    <dael> fantasai: Added b/c we had original set up scroll-snap-type where if it's non-inital it traps snaps. If elements inside asking for snap position we ignore. scroll cotnainers have to trap. Added additional behavior for scroll-snap-type so if someone wants to say in this area ignore a snap position they could do so
    <dael> fantasai: Seems this is difficult to impl for Blink. Do we want to not have the behavior? Would mean only way to prevent contents from having snap behavior is put in a scroll container
    <dael> Rossen_: It's a hack. The hack will work. People will hate the hack. It'll probably end up in css hacks books.
    <fantasai> https://github.com//issues/4496#issuecomment-706333521
    <dael> Rossen_: Is it really that difficult that we should go to that extent.
    <dael> fantasai: Here's comment from impl ^
    <dael> fantasai: I'm not aware of any requests for the behavior
    <dael> Rossen_: non-Blink impl with opinion?
    <dael> smfr: My hunch is it doesn't make sense for non-scrollable things to trap snapping
    <dael> fantasai: Within that element we don't track snap position
    <dael> Rossen_: Image in a carosel scenario?
    <dael> fantasai: No. a section and in that section there's properties setting snap points, you can turn that off. You can say this element ignore the snap positions. We can just not have that behavior and see if someone complaints
    <fantasai> s/positions/positions inside/
    <dael> Rossen_: In interest of time we can resolve here. If there are no strong arguments for keeping it I'm fine with that
    <dael> smfr: Looked at WK and would be easy to impl
    <dael> Rossen_: Argument for reverting doesn't seem to be a problem for WK
    <dael> Rossen_: What if we keep issue open and when we get to actual impl and get experience I think that's when we come back and decide
    <dael> fantasai: Mark at-risk?
    <dael> Rossen_: Sensible
    <dael> Rossen_: Objections?
    <dael> RESOLVED: Mark this property at-risk
  5. fantasai commented on Dec 16, 2020

    @fantasai
    Collaborator

    @majido Based on comments from WebKit, we ended up just marking this behavior at-risk. That means, if it's not implemented but everything else is, we'll drop the requirement; if it turns out to get implemented, it'll stay in the spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions