Skip to content

Commit b82cf97

Browse files
authored
[scroll-animations-1] Make timeline name scoping last-in-tree-order (w3c#13611)
See w3c#12581, w3c#13364.
1 parent 90a9a54 commit b82cf97

1 file changed

Lines changed: 169 additions & 71 deletions

File tree

scroll-animations-1/Overview.bs

Lines changed: 169 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,9 @@ spec:selectors-4; type:dfn; text:selector
534534
Specifies names for the [=named scroll progress timelines=]
535535
associated with this element.
536536

537+
Makes this element a [=weak timeline scope=]
538+
for the specified names.
539+
537540
### Axis of a Scroll Progress Timeline: the 'scroll-timeline-axis' property ### {#scroll-timeline-axis}
538541

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

986+
Makes this element a [=weak timeline scope=]
987+
for the specified names.
988+
983989
### Axis of a View Progress Timeline: the 'view-timeline-axis' property ### {#view-timeline-axis}
984990

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

10981104
## Named Timeline Scoping and Lookup ## {#timeline-scoping}
1105+
1106+
Named [=scroll progress timelines=] and [=view progress timelines=]
1107+
are referenceable within the subtree of a [=timeline scope=],
1108+
with the [=document element=] itself acting as an implicit default scope.
10991109

1100-
A named [=scroll progress timeline=] or [=view progress timeline=]
1101-
is referenceable by:
1102-
* the name-declaring element itself
1103-
* that element’s descendants
1104-
1105-
Note: The 'timeline-scope' property can be used
1106-
to declare the name of a timeline on an ancestor of its defining element,
1107-
effectively expanding its scope beyond that element’s subtree.
1110+
When there are multiple competing definitions
1111+
for the same name within the subtree of a [=timeline scope=],
1112+
the definition provided by the last element in [=flat tree=] order
1113+
takes precedence.
11081114

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

11181121
<div class=example>
1119-
Using ''timeline-scope'',
1120-
an element can refer to timelines
1121-
bound to elements that are siblings, cousins, or even descendants.
1122-
For example, the following creates an animation on an element
1123-
that is linked to a [=scroll progress timeline=]
1124-
defined by the subsequent sibling.
1125-
1126-
<xmp highlight=html>
1127-
<style>
1128-
@keyframes anim {
1129-
from { color: red; }
1130-
to { color: green; }
1131-
}
1122+
Say you have multiple instances of a component,
1123+
each defining a timeline
1124+
and some element using that timeline:
11321125

1133-
.root {
1134-
/* declares the scope of a '--scroller' timeline to reach all descendants */
1135-
timeline-scope: --scroller;
1136-
}
1126+
```html
1127+
<div>
1128+
<div class="component">
1129+
<div style="view-timeline: --v /*...*/;"></div>
1130+
<div style="animation-timeline: --v;"></div>
1131+
</div>
1132+
<div class="component">
1133+
<div style="view-timeline: --v /*...*/;"></div>
1134+
<div style="animation-timeline: --v;"></div>
1135+
</div>
1136+
</div>
1137+
```
11371138

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

1144-
.root .animation + .scroller {
1145-
/* attaches a scroll progress timeline to the timeline named '--scroller' */
1146-
scroll-timeline: --scroller;
1147-
}
1145+
We can fix this by making the component elements [=timeline scopes=]
1146+
for `--v`:
1147+
1148+
```html
1149+
<style>
1150+
.component {
1151+
timeline-scope: --v;
1152+
}
11481153
</style>
1149-
&hellip;
1150-
<section class="root">
1151-
<div class="animation">Animating Box</div>
1152-
<div class="scroller">Scrollable Box</div>
1153-
</section>
1154-
</xmp>
1154+
```
1155+
1156+
Now, any lookup of `--v` taking place within a component
1157+
will only see timelines defined by the component.
1158+
1159+
</div>
1160+
1161+
<div class=example>
1162+
Within a [=timeline scope=],
1163+
a named timeline can be referenced from any element in the same scope,
1164+
either before or after the timeline-providing element in tree-order.
1165+
1166+
```html
1167+
<div style="timeline-scope: --t">
1168+
<div style="animation-timeline: --t"></div>
1169+
<div style="scroll-timeline: --t"></div>
1170+
<div style="animation-timeline: --t"></div>
1171+
</div>
1172+
```
1173+
1174+
In the above example,
1175+
both instances of `animation-timeline:--t` find the same [=scroll progress timeline=]
1176+
named `--t`.
1177+
1178+
You can also reach `--t` from the timeline-providing element itself,
1179+
though this lookup would technically take place
1180+
in a separate [=weak timeline scope=]:
1181+
1182+
```html
1183+
<div style="scroll-timeline: --t; animation-timeline: --t"></div>
1184+
```
11551185
</div>
11561186

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

1668-
## Declaring a Named Timeline’s Scope: the 'timeline-scope' property ## {#timeline-scope}
1698+
## Declaring a Named Timeline’s Scope: the 'timeline-scope' property ## {#timeline-scope-property}
1699+
1700+
The 'timeline-scope' property
1701+
makes an element a [=strong timeline scope=]
1702+
for the specified timeline names.
16691703

16701704
<pre class="propdef">
16711705
Name: timeline-scope
16721706
Value: none | all | <<dashed-ident>>#
16731707
Initial: none
16741708
Applies to: all elements
16751709
Inherited: no
1676-
Computed value: the keyword ''timeline-scope/none'' or a list of [=CSS identifiers=]
1710+
Computed value: the keyword ''timeline-scope/none'',
1711+
the keyword ''timeline-scope/all'',
1712+
or a list of [=CSS identifiers=]
16771713
Animation type: not animatable
16781714
</pre>
16791715

1680-
This property declares the scope of the specified timeline names
1681-
to extend across this element’s subtree.
1682-
This allows a named timeline
1683-
(such as a [=named scroll progress timeline=] or [=named view progress timeline=])
1684-
to be referenced by elements outside the timeline-defining element’s subtree--
1685-
for example, by siblings, cousins, or ancestors.
1686-
It also blocks descendant timelines with the specified names
1687-
from being referenced from outside this subtree,
1688-
and ancestor timelines with the specified names from being referenced
1689-
within this subtree.
1690-
1691-
ISSUE(8915): There's some open discussion about these blocking effects.
1692-
16931716
Values have the following meanings:
16941717

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

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

17061728
<dt><dfn><<dashed-ident>></dfn>
17071729
<dd>
1708-
Declares the name of a matching named timeline defined by a descendant--
1709-
whose scope is not already explicitly declared by a descendant using 'timeline-scope'--
1710-
to be in scope for this element and its descendants.
1730+
The element is a [=strong timeline scope=]
1731+
for the specified names only.
1732+
</dl>
1733+
1734+
A <dfn>timeline scope</dfn> is an element which limits the visibility
1735+
of named timelines within the inclusive [=flat tree=] descendants of that element.
1736+
A reference to a named timeline
1737+
from an element within the subtree of a [=timeline scope=]
1738+
can only find timeline definitions provided by elements in the same subtree.
17111739

1712-
If no such timeline exists,
1713-
or if more than one such timeline exists,
1714-
instead declares an [=inactive timeline=] with the specified name.
1740+
Elements that are [=timeline scopes=]
1741+
can either be [=strong timeline scopes=],
1742+
or [=weak timeline scopes=]:
1743+
1744+
<dl>
1745+
<dt><dfn>strong timeline scope</dfn></dt>
1746+
<dd>
1747+
Named timelines defined on the [=timeline scope=] element
1748+
or any of its [=flat tree=] descendants
1749+
are only visible within that subtree.
1750+
1751+
<div class=example>
1752+
```html
1753+
<div id="e" style="scroll-timeline:--t; timeline-scope:--t">
1754+
<!-- This finds timeline --t ... -->
1755+
<div style="animation-timeline:--t"></div>
1756+
</div>
1757+
<!-- ... but this does not. -->
1758+
<div style="animation-timeline:--t"></div>
1759+
```
1760+
Note that `animation-timeline:--t` on `#e` itself
1761+
(the [=timeline scope=]) would also find `--t`;
1762+
`#e` counts as being *inside* the scope.
1763+
</div>
1764+
1765+
</dd>
1766+
1767+
<dt><dfn>weak timeline scope</dfn></dt>
1768+
<dd>
1769+
Acts like a [=strong timeline scope=],
1770+
except that timelines defined on the [=timeline scope=] element itself
1771+
are also visible on the outside
1772+
of the subtree.
1773+
1774+
Note: Lookups from an element that is a [=weak timeline scope=]
1775+
are still subject to visibility restrictions;
1776+
if that element defines a timeline `--t`,
1777+
then `animation-timeline:--t` on the same element
1778+
always refers to that timeline.
1779+
1780+
<div class=example>
1781+
Using 'scroll-timeline' on an element
1782+
makes it a [=weak timeline scope=]:
1783+
1784+
```html
1785+
<div id="e" style="scroll-timeline:--t">
1786+
<!-- This finds the timeline --t ... -->
1787+
<div style="animation-timeline:--t"></div>
1788+
</div>
1789+
<!-- ... and this does too. -->
1790+
<div style="animation-timeline:--t"></div>
1791+
```
1792+
1793+
Had we defined a second timeline
1794+
in the outer scope
1795+
on an element appearing <em>after</em> `#e` in [=flat tree=] order,
1796+
the outer reference would now see that timeline instead:
1797+
1798+
```html
1799+
<div id="e" style="scroll-timeline:--t">
1800+
<!-- This finds the timeline --t, declared immediately above. -->
1801+
<div style="animation-timeline:--t"></div>
1802+
</div>
1803+
<!-- This also finds a timeline, but it finds the timeline defined
1804+
on its subsequent sibling. -->
1805+
<div style="animation-timeline:--t"></div>
1806+
<div style="scroll-timeline:--t"></div> <!-- Wins in outer scope. -->
1807+
```
1808+
</div>
1809+
</dd>
17151810
</dl>
17161811

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

17211816
# Changes # {#changes}
17221817

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

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

0 commit comments

Comments
 (0)