Skip to content

[css-scroll-snap-1] re-snapping after layout with animations #4609

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
majido opened this issue Dec 16, 2019 · 5 comments
Closed

[css-scroll-snap-1] re-snapping after layout with animations #4609

majido opened this issue Dec 16, 2019 · 5 comments
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-scroll-snap-1 Current Work

Comments

@majido
Copy link
Contributor

majido commented Dec 16, 2019

Context

The specification requires the browsers to re-snap after any content/layout changes. It also prefers re-snapping to the same element as before but if that element never existed or no longer exists then snapping to a new element is done.

We have been implementing this in Chrome and noticed an interesting implication of this: if one adds a single snap area to an existing snap container with no snap area, the container has to snap to the area.

This introduces an interesting new way to do "scroll-into-view" effects using only css. For example see this demo where I make the :active element to be a snap area which forces its ancestor scroller to re-snap which centers the element. I think this is interesting usecase of scroll-snap. However one limitation of this is that at the moment these re-snapping effects are not necessarily animated so the re-snap is jarring. Also webdevs don't have any control on such animations if we add them. I like to see if we can rectify this by making it animated but also exposing more control over such snap animations to web-devs.

Current Chrome Behavior

In Chrome we have decided to not animate layout-induced re-snapping in general. I think this makes sense in most re-snapping cases where we are re-snapping to the same element and the scroll snapping effect should not really be noticed by the user. But when we are re-snapping to a different element I think we should consider allowing animations.

The specification leaves it up to user agent whether to animate or not animate any particular snap operations. So we could just animate these in Chrome and I plan to experiment with this. At the same time I think it makes sense to give web authors control on the animation aspect of scroll-snapping since in some usecases they may not want any animations. Below I suggest one proposal to do this.

Proposal

We already have scroll-behavior to control programmatic scroll animations. So a simple solution is to have its definition expanded to control any scroll snap animation as a result of CSSOM scrolling APIs or re-snapping.

So the proposal suggestion has two parts:

A) Continue to leave animation decision up to user-agent but add a note that suggest user agent should consider animating when re-snap to different element.

B) Specify that scroll-behavior controls any scroll-snap animations that are not initiated by user. (This includes any CSSOM scrolling APIs that snap which I think they already did, and more importantly any animations that is introduced due to re-snapping)

Here is btw is the current wording for scroll-behavior:

The scroll-behavior property specifies the scrolling behavior for a scrolling box, when scrolling happens due to navigation or CSSOM scrolling APIs. Any other scrolls, e.g. those that are performed by the user, are not affected by this property. When this property is specified on the root element, it applies to the viewport instead.

@majido majido added the css-scroll-snap-1 Current Work label Dec 16, 2019
@majido majido assigned majido and unassigned majido Dec 16, 2019
@fantasai
Copy link
Collaborator

Interesting point!

So I think the actions we should take to accept your proposal are:

  • rework the wording to make these two cases a little more distinct, so that they can be thought of as separate cases with some terminology to be able to reference them
  • recommend no animation in the "didn't change elements" case, to help anchor the view on it
  • suggest that the "snapped to a new element" case be treated scrolling-wise the same way as navigating to that element some other way, such as using .scrollIntoView() or .focus()), and should be subject to scroll-behavior accordingly
  • clarify the definition of scroll-behavior to match the above

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed re-snapping after layout with animations, and agreed to the following:

  • RESOLVED: Require smooth scrolling behavior when there is a new snap, but let UA decide when it's re-snapping to the same element.
The full IRC log of that discussion <heycam> Topic: re-snapping after layout with animations
<heycam> github: https://github.com//issues/4609
<heycam> fantasai: re-snapping can be triggered in different cases
<heycam> ... if you're snapped to an element, and the layout change
<heycam> ... another one is a new snap position exists, or now you're in range of a snap position and you weren't before
<heycam> ... scrolling is sometimes animated, sometimes not
<heycam> ... there's a scroll-beahvior property that controls programmatic scroll animations
<heycam> ... majid is saying that the scroll-behavior should probably also control the prgorammatic scroll behavior that's triggered by scroll snapping
<heycam> ... and you might want to treat re-snapping to same elemetn differently from "not snapped, but not you're going to snap"
<heycam> ... one proposal is to define that the snapped to a new element case be treated scrolling wise as the same as scrollIntoView() or focus()
<heycam> ... and then therefore define that this should be subject to scroll-behavior
<heycam> .. .the other thing w could do is to allow the UA do something different for the re-snap case
<heycam> ... but in the case where you weren't snapped before, those cases should be animated in the same way scrollIntoView animates, and thus be subject to scroll-behavior
<heycam> myles: why standardize this at all? why not say nothing?
<heycam> TabAtkins: because Majid finds that the smooth scrolling behavior for the new snap position seems reasonable for the author to want to depend on
<heycam> ... for the same reason scrolling to random things from JS be guaranteed smooth
<heycam> fantasai: also clarifies interaction with scroll-behaviior
<heycam> myles: how about the re-snapping behavior?
<heycam> fantasai: I think we want to say something about it to make sure it's seen as distinct
<heycam> ... we need to distinguish the re-snap case to be UA dependent so that scroll-behavior is not required to affect it
<tantek_> as a user I may want a more responsive UI and set all the scroll behaviors to 'instant'
<tantek_> like I want a way to turn-off cheesy animations
<heycam> fantasai: don't feel the need to require not animating in that case, but should suggest it's possible
<heycam> ... the goal of this re-snapping is to make the user feel that the layout changed but I didn't scroll
<heycam> ... you don't want to animate to get back to where you were
<heycam> myles: I think it depends how much of the viewport space the element takes up
<heycam> ... if it's a small element, having most of what the user see jump to a different position would look jarring, but if the element covers most of the viewport, then jumping makes more sense
<heycam> TabAtkins: that's reaosnable
<heycam> ... as long as we distinguish it so that these cases are separate
<fantasai> s/more sense/more sense. So would prefer may rather than should/
<heycam> RESOLVED: Require smooth scrolling behavior when there is a new snap, but let UA decide when it's re-snapping to the same element.

@fantasai
Copy link
Collaborator

Added the following paragraph to the re-snapping section:

Scrolling required by a re-snap operation to a new or different box must behave and animate the same way as any other scroll-into-view operation, including honoring controls such as 'scroll-behavior'. Scrolling behavior for re-snapping to the same box as before however, is UA-defined. The UA may, for example, when snapped to the start of a section, choose not to animation the scroll to the section’s new position as content is dynamically added earlier in the document in order to create the illusion of not scrolling.

And made the following edits to 'scroll-behavior':

The scroll-behavior property specifies the scrolling behavior for a scrolling box, when scrolling happens due to navigation, or CSSOM scrolling APIs, or scroll snapping operations not initiated by the user [[!CSS-SCROLL-SNAP-1]]. Any other scrolls, e.g. those that are performed by the user, are not affected by this property.

@majido @tabatkins @smfr Lmk if the edits look good.

@majido
Copy link
Contributor Author

majido commented Oct 9, 2020

This edits lgtm and achieve the desired outcome. Thanks for the edit. /cc @flackr

@majido
Copy link
Contributor Author

majido commented Oct 9, 2020

Filed an issue for Blink

@fantasai fantasai added Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. and removed Commenter Response Pending labels Nov 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-scroll-snap-1 Current Work
Projects
None yet
Development

No branches or pull requests

3 participants