-
Notifications
You must be signed in to change notification settings - Fork 747
Description
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 ofanimation-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 containerroot
references the main viewport scroller<container-name>
references thecontainer-name
property: it filters the lookup to the nearest scroll container with the givencontainer-name
. (See css-contain-3.)- The default direction is
block
; the default scroll container lookup isnearest
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.)