Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 169 additions & 71 deletions scroll-animations-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,9 @@ spec:selectors-4; type:dfn; text:selector
Specifies names for the [=named scroll progress timelines=]
associated with this element.

Makes this element a [=weak timeline scope=]
for the specified names.

### Axis of a Scroll Progress Timeline: the 'scroll-timeline-axis' property ### {#scroll-timeline-axis}

<pre class='propdef'>
Expand Down Expand Up @@ -980,6 +983,9 @@ spec:selectors-4; type:dfn; text:selector
Specifies names for the [=named view progress timelines=]
associated with this element.

Makes this element a [=weak timeline scope=]
for the specified names.

### Axis of a View Progress Timeline: the 'view-timeline-axis' property ### {#view-timeline-axis}

<pre class='propdef'>
Expand Down Expand Up @@ -1096,62 +1102,86 @@ spec:selectors-4; type:dfn; text:selector
any real use cases for multiple iterations here.

## Named Timeline Scoping and Lookup ## {#timeline-scoping}

Named [=scroll progress timelines=] and [=view progress timelines=]
are referenceable within the subtree of a [=timeline scope=],
with the [=document element=] itself acting as an implicit default scope.

A named [=scroll progress timeline=] or [=view progress timeline=]
is referenceable by:
* the name-declaring element itself
* that element’s descendants

Note: The 'timeline-scope' property can be used
to declare the name of a timeline on an ancestor of its defining element,
effectively expanding its scope beyond that element’s subtree.
When there are multiple competing definitions
for the same name within the subtree of a [=timeline scope=],
the definition provided by the last element in [=flat tree=] order
takes precedence.

If multiple elements have declared the same timeline name,
the matching timeline is the one declared
on the nearest element in tree order.
In case of a name conflict on the same element,
names declared later in the naming property
('scroll-timeline-name', 'view-timeline-name')
take precedence, and
[=scroll progress timelines=] take precedence over [=view progress timelines=].

<div class=example>
Using ''timeline-scope'',
an element can refer to timelines
bound to elements that are siblings, cousins, or even descendants.
For example, the following creates an animation on an element
that is linked to a [=scroll progress timeline=]
defined by the subsequent sibling.

<xmp highlight=html>
<style>
@keyframes anim {
from { color: red; }
to { color: green; }
}
Say you have multiple instances of a component,
each defining a timeline
and some element using that timeline:

.root {
/* declares the scope of a '--scroller' timeline to reach all descendants */
timeline-scope: --scroller;
}
```html
<div>
<div class="component">
<div style="view-timeline: --v /*...*/;"></div>
<div style="animation-timeline: --v;"></div>
</div>
<div class="component">
<div style="view-timeline: --v /*...*/;"></div>
<div style="animation-timeline: --v;"></div>
</div>
</div>
```

.root .animation {
animation: anim;
/* references the '--scroller' timeline for driving the progress of 'anim' */
animation-timeline: --scroller;
}
The problem with this is that multiple definitions of `--v`
exist in the same [=timeline scope=];
both instances of `animation-timeline:--v`
find the *same* timeline,
i.e. the last one seen in [=flat tree=] order.

.root .animation + .scroller {
/* attaches a scroll progress timeline to the timeline named '--scroller' */
scroll-timeline: --scroller;
}
We can fix this by making the component elements [=timeline scopes=]
for `--v`:

```html
<style>
.component {
timeline-scope: --v;
}
</style>
&hellip;
<section class="root">
<div class="animation">Animating Box</div>
<div class="scroller">Scrollable Box</div>
</section>
</xmp>
```

Now, any lookup of `--v` taking place within a component
will only see timelines defined by the component.

</div>

<div class=example>
Within a [=timeline scope=],
a named timeline can be referenced from any element in the same scope,
either before or after the timeline-providing element in tree-order.

```html
<div style="timeline-scope: --t">
<div style="animation-timeline: --t"></div>
<div style="scroll-timeline: --t"></div>
<div style="animation-timeline: --t"></div>
</div>
```

In the above example,
both instances of `animation-timeline:--t` find the same [=scroll progress timeline=]
named `--t`.

You can also reach `--t` from the timeline-providing element itself,
though this lookup would technically take place
in a separate [=weak timeline scope=]:

```html
<div style="scroll-timeline: --t; animation-timeline: --t"></div>
```
</div>

## Animation Events ## {#events}
Expand Down Expand Up @@ -1665,65 +1695,133 @@ spec:selectors-4; type:dfn; text:selector
which allows declaring a timeline name’s scope on an ancestor
of the timeline’s defining element.

## Declaring a Named Timeline’s Scope: the 'timeline-scope' property ## {#timeline-scope}
## Declaring a Named Timeline’s Scope: the 'timeline-scope' property ## {#timeline-scope-property}

The 'timeline-scope' property
makes an element a [=strong timeline scope=]
for the specified timeline names.

<pre class="propdef">
Name: timeline-scope
Value: none | all | <<dashed-ident>>#
Initial: none
Applies to: all elements
Inherited: no
Computed value: the keyword ''timeline-scope/none'' or a list of [=CSS identifiers=]
Computed value: the keyword ''timeline-scope/none'',
the keyword ''timeline-scope/all'',
or a list of [=CSS identifiers=]
Animation type: not animatable
</pre>

This property declares the scope of the specified timeline names
to extend across this element’s subtree.
This allows a named timeline
(such as a [=named scroll progress timeline=] or [=named view progress timeline=])
to be referenced by elements outside the timeline-defining element’s subtree--
for example, by siblings, cousins, or ancestors.
It also blocks descendant timelines with the specified names
from being referenced from outside this subtree,
and ancestor timelines with the specified names from being referenced
within this subtree.

ISSUE(8915): There's some open discussion about these blocking effects.

Values have the following meanings:

<dl dfn-for="timeline-scope" dfn-type=value>
<dt><dfn>none</dfn>
<dd>
No changes in timeline name scope.
The element is not a [=strong timeline scope=] for any name.

<dt><dfn>all</dfn>
<dd>
Declares the names of all timelines defined by descendants--
whose scope is not already explicitly declared by a descendant using 'timeline-scope'--
to be in scope for this element and its descendants.
The element is a [=strong timeline scope=]
for *all* timeline names.

<dt><dfn><<dashed-ident>></dfn>
<dd>
Declares the name of a matching named timeline defined by a descendant--
whose scope is not already explicitly declared by a descendant using 'timeline-scope'--
to be in scope for this element and its descendants.
The element is a [=strong timeline scope=]
for the specified names only.
</dl>

A <dfn>timeline scope</dfn> is an element which limits the visibility
of named timelines within the inclusive [=flat tree=] descendants of that element.
A reference to a named timeline
from an element within the subtree of a [=timeline scope=]
can only find timeline definitions provided by elements in the same subtree.

If no such timeline exists,
or if more than one such timeline exists,
instead declares an [=inactive timeline=] with the specified name.
Elements that are [=timeline scopes=]
can either be [=strong timeline scopes=],
or [=weak timeline scopes=]:

<dl>
<dt><dfn>strong timeline scope</dfn></dt>
<dd>
Named timelines defined on the [=timeline scope=] element
or any of its [=flat tree=] descendants
are only visible within that subtree.

<div class=example>
```html
<div id="e" style="scroll-timeline:--t; timeline-scope:--t">
<!-- This finds timeline --t ... -->
<div style="animation-timeline:--t"></div>
</div>
<!-- ... but this does not. -->
<div style="animation-timeline:--t"></div>
```
Note that `animation-timeline:--t` on `#e` itself
(the [=timeline scope=]) would also find `--t`;
`#e` counts as being *inside* the scope.
</div>

</dd>

<dt><dfn>weak timeline scope</dfn></dt>
<dd>
Acts like a [=strong timeline scope=],
except that timelines defined on the [=timeline scope=] element itself
are also visible on the outside
of the subtree.

Note: Lookups from an element that is a [=weak timeline scope=]
are still subject to visibility restrictions;
if that element defines a timeline `--t`,
then `animation-timeline:--t` on the same element
always refers to that timeline.

<div class=example>
Using 'scroll-timeline' on an element
makes it a [=weak timeline scope=]:

```html
<div id="e" style="scroll-timeline:--t">
<!-- This finds the timeline --t ... -->
<div style="animation-timeline:--t"></div>
</div>
<!-- ... and this does too. -->
<div style="animation-timeline:--t"></div>
```

Had we defined a second timeline
in the outer scope
on an element appearing <em>after</em> `#e` in [=flat tree=] order,
the outer reference would now see that timeline instead:

```html
<div id="e" style="scroll-timeline:--t">
<!-- This finds the timeline --t, declared immediately above. -->
<div style="animation-timeline:--t"></div>
</div>
<!-- This also finds a timeline, but it finds the timeline defined
on its subsequent sibling. -->
<div style="animation-timeline:--t"></div>
<div style="scroll-timeline:--t"></div> <!-- Wins in outer scope. -->
```
</div>
</dd>
</dl>

Note: This property cannot affect or invalidate any timeline name lookups
within the subtree of a descendant element that declares the same name.
See [[#timeline-scope]].
When an element is both a [=strong timeline scope=]
and a [=weak timeline scope=] for the same name,
it behaves like a [=strong timeline scope=] for that name.

# Changes # {#changes}

Changes since the
(<a href="https://www.w3.org/TR/2023/WD-scroll-animations-1-20230428/">28 April 2023</a>)
Working Draft include:

* Changed timeline name scoping to use nearest-ancestor and last-in-tree-order resolution.
(<a href="https://github.com/w3c/csswg-drafts/issues/12581">Issue 12581</a>),
(<a href="https://github.com/w3c/csswg-drafts/issues/13364">Issue 13364</a>)
* Allow ''all'' as a value for 'timeline-scope'.
(<a href="https://github.com/w3c/csswg-drafts/issues/9158">Issue 9158</a>)
* Removed <css>scroll-timeline-attachment</css> and <css>view-timeline-attachment</css> in favor of 'timeline-scope'.
Expand Down