8000 [css-scroll-animations] Rethinking declarative syntax for scroll-linked animations · Issue #6674 · w3c/csswg-drafts · GitHub
[go: up one dir, main page]

Skip to content

[css-scroll-animations] Rethinking declarative syntax for scroll-linked animations #6674

@fantasai

Description

@fantasai

Overview

@mirisuzanne and I reviewed the Scroll-linked Animations ED this week. We have some concerns (which are at a high level similar to Robert O'Callahan's concerns with the initial proposals for “CSS Snap Points” that became the current CSS Scroll Snap Module):

  • The model seems to rely a lot on explicit offsets, rather than on element positions. Typically the reason for using offsets is to align with elements.
  • There is functionality to use element-based offsets, but these rely on ID selectors, which are not particularly portable across pages and makes it impossible for styles to be re-used in multiple places on the same page.

We'd like to propose a replacement of the declarative syntax in this module that addresses these problems. Note: This is part of our larger proposal rethinking various features for animation timelines and interpolation and how to fit them all together.

Our suggestion splits scroll-linked animation timelines into two types: those linked to the scroll timeline as a whole, and those linked to the portion of it in which a particular element participates.

Animations linked to scroll progress as timeline

These are animations whose timeline goes from 0% to 100% based on the scroll position of an ancestor scroll container.

animation-timeline: scroll()

The idea is to use an inline functional notation to identify the timeline using the animation-timeline property, expanding the property's syntax as follows:

animation-timeline: auto | scroll(<scroll-direction>? <scroller>?);
<scroll-direction> = block | inline | vertical | horizontal
<scroller> = root | nearest | <container-name>
  • auto is the initial value of animation-timeline, and behaves as animations have always done, triggering on application of the animation and lasting for the specified duration and delay.
  • nearest references the nearest ancestor scroll container
  • root references the main viewport scroller
  • <container-name> references the container-name property: it filters the lookup to the nearest scroll container with the given container-name. (See css-contain-3.)
  • The default direction is block; the default scroll container lookup is nearest

animation-timeline: NAME

Alternately, some scroll-timeline properties could be defined, which when applied to a scroll container would allow naming its timeline for a more indirect but reusable approach.

scroll-timeline-name: <custom-ident>#;
scroll-timeline-direction: <scroll-direction>#;
scroll-timeline: [<scroll-direction>? <custom-ident>]#;

Such named scroll timelines would be referenceable by name from the animation-timeline property.

animation-timeline: auto | <timeline-name>

Animations linked to view progress as timeline

Often animations are desired to start and end while a particular element is in view within the scroller. This timeline is essentially a snippet of the scroller's complete timeline, with 0% and 100% pinned to the moment the element comes into view and the moment it leaves view.

view-timeline-name: <custom-ident>
view-timeline-inset:  [ auto | <length-percentage> ]{1,4}
view-timeline-fit:  [ cover | contain | <percentage> ]
  • view-timeline-name - Specifies a name for this element's in-view timeline, so that it can be referenced by descendant and sibling elements as their animation-timeline.
  • view-timeline-inset - Specifies an inset (positive) or outset (negative) adjustment of the scrollport when considering whether the element is in view. auto indicates to use the value of scroll-padding. Initial value is zero. Percentages are with reference to the scrollport.
  • view-timeline-fit - Specifies whether the in-view timeline is measured from the moment any part of the box comes into view until all parts leave it (cover/0%) or whether it is measured from the moment all parts of the box come into view until any part leaves it (contain/100%). Initial value is 0% (cover).

Scope of Scroll-linked Timelines

The scope of a scroll-linked timeline (which elements can call it by name via animation-timeline) is defined as:

  • its descendants
  • its siblings (and their descendants)

This basically means its scope is attached to its parent, but the parent can't use it. In case of multiple timelines with the same name being in scope, the timeline associated with its nearest ancestor wins.

(It might also be useful to allow the scope to expand outside this parent, giving ancestors and far cousins access to the timeline across the document. In all cases the timeline reached via the closest ancestor should win in case of conflict. But this kind of global scoping from descendant elements might be difficult to implement.)

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

      0