Navigation Menu

Skip to content
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

CSS Snap Points: Event Model Missing #156

Open
scottjehl opened this issue May 31, 2016 · 18 comments
Open

CSS Snap Points: Event Model Missing #156

scottjehl opened this issue May 31, 2016 · 18 comments

Comments

@scottjehl
Copy link

It would be useful if CSS Snap Points had an event model for events like say, snapstart, snapstop, and snapchange. Currently, we can listen for scroll events and try to simulate these events, but it's hard to pinpoint when a native snap starts and ends, as opposed to a user-driven scroll.

@gregwhitworth gregwhitworth added the css-scroll-snap-1 Current Work label May 31, 2016
@tabatkins
Copy link
Member

Yeah, def.

@fantasai
Copy link
Collaborator

Note: In the interest of wrapping up the existing set of functionality (which is well-specced and pretty much done), we're deferring the event model until a later level of CSS Scroll Snap.

birtles added a commit to birtles/csswg-drafts that referenced this issue Dec 4, 2017
As far as I can tell, this produces the correct result in all cases.

This closes w3c#156.
@pavelkornev
Copy link

Up. @fantasai Isn't it time?

@fantasai
Copy link
Collaborator

@pavelkornev It is. I unfortunately don't have the expertise to draft something up, but I'm happy to accept proposals. :) They'd go into Level 2, but we can certainly start a draft as soon as there's something to put in it.

@tunelinks
Copy link

tunelinks commented May 2, 2019

I believe if a user scrolls or shrinks their viewport the snap should move the scrollbar to the center so it can be more responsive. Please see this for example and move your scrollbar to another position and then shrink the browser. https://codepen.io/anon/pen/jRjpQv

@jonjohnjohnson
Copy link

@tunelinks your concerns are already handled in the spec with this language...

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.
https://drafts.csswg.org/css-scroll-snap/#snap-strictness

Though implementors have yet to implement this logic. Chime in on filings like these to encourage implementation.

Also, your concern isn't exactly related to the original issue above.

@DrummerHead
Copy link

Is this what I need to know to make a spec proposal? Or is there more documentation?

@frivoal
Copy link
Collaborator

frivoal commented Sep 25, 2019

@DrummerHead, yes, that (and the things linked from it) is a good starting point. I would also add that it is usually recommended to be very explicit about the uses cases you are trying to solve with your proposal. A problem that is obvious to you may not always be obvious to others, and unless we all understand what it is that we're trying to solve, it can be hard to agree on the best way to solve it.

@fantasai
Copy link
Collaborator

fantasai commented Oct 9, 2019

@DrummerHead The TAG drafted an "explainer explainer", which is maybe a good starting point. But basically, a proposal to solve this needs to A) define some syntax, B) explain at least at a high level the expected behavior, and C) explain some of the use cases it solves, with some examples. It doesn't have to be super formal, just so long as it communicates those three things. :)

@zeluspudding
Copy link

zeluspudding commented Nov 12, 2019

C) explain some of the use cases it solves

Would the events api be the only way to build pagination for a slider (to indicate which slide I'm on)? I currently need this but am not aware of a way to extract the current dom's index using the current CSS Snap Scroll implementation (here's a codepen).
.. this makes me think (in the mean time) that I have to revert to a javscript scroll slider? Is that true?

UPDATE
Here's how I detect that a scroll has completed / update the current index. Not sure it's the best but it works.

@SebastianZ
Copy link
Contributor

Just to get the ball rolling, here is how I imagine an event model for scroll snapping could look like:

Syntax

snapped event

Type: snapped
Interface: SnapEvent
Sync / Async: Sync
Bubbles: Yes
Trusted Targets: Element
Cancelable: No
Composed: Yes
Default action: None
Context (trusted events):

  • Event.target: event target snapping the scrollport
  • UIEvent.view: Window
  • UIEvent.detail: 0
  • SnapEvent.relatedTarget: previous event target snapping the scrollport
  • SnapEvent.scrollContainer: scroll container the event target is in
  • SnapEvent.inlineSnapPosition: box's snap position in the inline axis as an alignment of its snap area
  • SnapEvent.blockSnapPosition: box's snap position in the block axis as an alignment of its snap area
interface SnapEvent {
	readonly attribute EventTarget? relatedTarget = null;
	readonly attribute EventTarget scrollContainer;
	readonly attribute DOMString inlineSnapPosition;
	readonly attribute DOMString blockSnapPosition;
};

Expected behavior

The snapped event is dispatched on the scroll container after snapping happened at a snap position. This allows an author to know when snapping happened and what caused it.

Use cases

  • Knowing the element where snapping happened in order to get the number of a slide in a presentation or adjust the indicator for the currently shown image in a gallery.
  • Styling the scroll container or the snapping element differently when snapping.
  • Knowing how an element snapped to be able to adjust the layout and styling of other elements.

That's just a rough draft and I probably missed some use cases and things required to cover them. Also note that the snapped event defined here is triggered after snapping has happened, as I couldn't come up with use cases in which you'd want an event that is triggered before snapping. Though maybe there are cases in which you want to know beforehand when snapping will happen and maybe be able to cancel it.

So I encourage everyone to comment on this idea and come up with more use cases.

@scottjehl You mentioned three events, though I am not sure what snapstart and snapstop were meant to be for and when they should be triggered. I assume the snapped event I described is what you called snapchange.

Sebastian

@frivoal
Copy link
Collaborator

frivoal commented Sep 19, 2020

maybe there are cases in which you want to know beforehand when snapping will happen and maybe be able to cancel it.

I suspect it's better to leave this out (as you did) unless there are extremely compelling use cases for that. Having potentially blocking JS calls in the middle of scrolling tends make browser engineers very sad.

Other questions:

  • Is your event supposed to be fired when the browser has landed on the snapped position and stopped moving, or as soon as it has decided on a snap position, even though it might still be moving towards it? (I think it's the former, but it's good to be clear)
  • If the user starts scrolling away from a snap point, but not very far, releases, and the browser snaps back to the same one, do we fire a new event because we resnapped, or not, because we effectively didn't leave the snappoint?
  • Same question as above, but with the user resizing the window rather than scrolling.
  • Same question as above, but with the "resnapping" being triggered by a change in content / styling
  • If the snap poisition is continuously moving due to an animation or a transition, and the browser continuously tracking it, do we send a stream a events because we're continuously resnapping, or not because we never leave the snapped state?

@smfr
Copy link
Contributor

smfr commented Sep 20, 2020

Proposals here should also keep in mind the proposed scrollend event: https://github.com/WICG/overscroll-scrollend-events

@SebastianZ
Copy link
Contributor

SebastianZ commented Sep 20, 2020

Other questions:

  • Is your event supposed to be fired when the browser has landed on the snapped position and stopped moving, or as soon as it has decided on a snap position, even though it might still be moving towards it? (I think it's the former, but it's good to be clear)

When the browser has landed on the snapped position and stopped moving. The "decided on a snap position" case is probably meant by the snapstart event mentioned by @scottjehl.

  • If the user starts scrolling away from a snap point, but not very far, releases, and the browser snaps back to the same one, do we fire a new event because we resnapped, or not, because we effectively didn't leave the snappoint?

A new event should be fired. The author can distinguish this re-snapping by checking event.target === event.relatedTarget if necessary.

  • Same question as above, but with the user resizing the window rather than scrolling.

I tend to say yes for that case, because the snap position can change in that case. Not necessarily when the scroll container was already snapped before the change and is snapped to the same position after the resizing, as the spec. requires to re-snap at that position in that case. Though for consistency the event might also be triggered in that case.

  • Same question as above, but with the "resnapping" being triggered by a change in content / styling

Same as above.

  • If the snap position is continuously moving due to an animation or a transition, and the browser continuously tracking it, do we send a stream a events because we're continuously resnapping, or not because we never leave the snapped state?

As far as I can see, the specification currently doesn't define what happens for animations and transitions, i.e. whether snap positions are continuously adjusted or just when the animation or transition ends.

If the snapped state is never left and the scroll container stays snapped at the same snap position, I'd say no event should be fired.

Generally speaking, everytime the snapped state changes from "not snapped" to "snapped" a new snapped event should be fired.

Sebastian

@SebastianZ
Copy link
Contributor

Proposals here should also keep in mind the proposed scrollend event: https://github.com/WICG/overscroll-scrollend-events

Thank you for the note, @smfr! The information related to snapping for the proposed snapped event might be mingled into the scrollend event, as both happen after the scrolling action has finished. Though I believe both events are distinct enough to be handled separately. This is especially true if we consider adding several events related to snapping.

The order in which they'd get fired is probably not that important as both are defined not to be cancelable and scrollend is currently defined as being async, but logically snapping causes the scroll action to end, so I'd say snapped before scrollend.

Sebastian

@Schepp
Copy link

Schepp commented Sep 21, 2020

I would like to also point to this request by me, aiming in a similar direction: https://webwewant.fyi/wants/65/

This is not just about events, but also about offering some sort of Scroll Snap API to programmatically scroll to certain snap points. As for the events, I proposed these two things which might be worth considering here:

  1. I'd like to have a snap event, once the element has snapped to a point, with info on which snap point of how many total snap points it just snapped to, so that I can update a progress indicator.
  1. I'd like to see the scroll event getting a new property which tells me if a scroll event was user-created or if it results from automatic scrolling (also interesting for the smooth scrolling coming from CSS scroll-behavior).

@fvpDev
Copy link

fvpDev commented Sep 23, 2022

Hey y'all! As a young web dev I am super excited for the implementation of this. How's it coming along? Also, thank you for being awesome!

@SebastianZ
Copy link
Contributor

@Schepp

This is not just about events, but also about offering some sort of Scroll Snap API to programmatically scroll to certain snap points.

I agree that there should be a way to explicitly scroll to certain snap points. Though I believe that should be discussed separately from the event model discussed here. So I created #8558 for it.

  1. I'd like to have a snap event, once the element has snapped to a point, with info on which snap point of how many total snap points it just snapped to, so that I can update a progress indicator.

Does this really require to know how many snap points there are? I think for a progress indicator it should be enough to know the target element. With that, you can easily calculate the progress.

  1. I'd like to see the scroll event getting a new property which tells me if a scroll event was user-created or if it results from automatic scrolling (also interesting for the smooth scrolling coming from CSS scroll-behavior).

Can you tell a concrete use case that requires a distinction between the two methods?

Sebastian

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