From ab661ab515a86f36dfb944529a22bbf5575cd619 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 14:49:06 +0100 Subject: [PATCH 01/28] [scroll-animations-1] Add examples (WIP) --- scroll-animations-1/Overview.bs | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index a95c1c18672d..8821c25417fe 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -238,6 +238,14 @@ spec:selectors-4; type:dfn; text:selector References to the [=root element=] propagate to the document viewport (which functions as its [=scroll container=]). +
+ Creation of an anonymous [=Scroll progress timeline=] with ''scroll()'' + + ```css + // TODO + ``` +
+ Each use of ''scroll()'' corresponds to its own instance of {{ScrollTimeline}} in the Web Animations API, even if multiple elements use ''scroll()'' to refer @@ -335,6 +343,14 @@ spec:selectors-4; type:dfn; text:selector The values of {{ScrollTimeline/source}} and {{AnimationTimeline/currentTime}} are both computed when either is requested or updated. +
+ Example with {{ScrollTimeline}} + + ```js + // TODO + ``` +
+ ## Named Scroll Progress Timelines ## {#scroll-timelines-named} [=Scroll progress timelines=] can also be defined on the [=scroll container=] itself, @@ -349,6 +365,14 @@ spec:selectors-4; type:dfn; text:selector with 'scroll-timeline-name' as the [=coordinating list base property=]. See [[css-values-4#linked-properties]]. +
+ Creation of a [=named scroll progress timeline=]: + + ```css + // TODO + ``` +
+ ### Naming a Scroll Progress Timeline: the 'scroll-timeline-name' property ### {#scroll-timeline-name}
@@ -560,6 +584,14 @@ spec:selectors-4; type:dfn; text:selector
 	of the [=view progress visibility range=],
 	as defined for 'view-timeline-inset'.
 
+	
+ Creation of an anonymous [=View progress timeline=] with ''view()'': + + ```css + // TODO + ``` +
+ Each use of ''view()'' corresponds to its own instance of {{ViewTimeline}} in the Web Animations API, even if multiple elements use ''view()'' to reference @@ -670,6 +702,14 @@ spec:selectors-4; type:dfn; text:selector The values of {{ViewTimeline/subject}}, {{ScrollTimeline/source}}, and {{AnimationTimeline/currentTime}} are all computed when any of them is requested or updated. +
+ Example with {{ViewTimeline}} + + ```js + // TODO + ``` +
+ ## Named View Progress Timelines ## {#view-timelines-named} [=View progress timelines=] can also be defined declaratively @@ -684,6 +724,14 @@ spec:selectors-4; type:dfn; text:selector with 'view-timeline-name' as the [=coordinating list base property=]. See [[css-values-4#linked-properties]]. +
+ Creation of a [=named view progress timeline=]: + + ```css + // TODO + ``` +
+ ### Naming a View Progress Timeline: the 'view-timeline-name' property ### {#view-timeline-name}
@@ -770,6 +818,22 @@ spec:selectors-4; type:dfn; text:selector
 	can also be further restricted to a particular timeline range
 	(see [[#named-range-animation-declaration]]).
 
+	
+ Example of a [=named scroll progress timeline=]: + + ```css + // TODO + ``` +
+ +
+ Example of a {{ViewTimeline}}: + + ```css + // TODO + ``` +
+ Time-based delays ('animation-delay') get converted to their respective proportions as described in [[web-animations-2#animations]] @@ -1021,6 +1085,12 @@ spec:selectors-4; type:dfn; text:selector are only generated for properties that don't have keyframes at or earlier than 0% or at or after 100% (respectively). +
+ ```css + // TODO + ``` +
+ ## Attaching Animations to Timeline Ranges ## {#named-range-animation-declaration} A set of animation keyframes can be attached @@ -1109,6 +1179,12 @@ spec:selectors-4; type:dfn; text:selector
+
+ ```css + // TODO: EXAMPLE with <> + ``` +
+ ISSUE(8438): What's the best way to handle defaulting of omitted values here? ### Specifying an Animation’s Timeline Range Start: the 'animation-range-start' property ### {#animation-range-start} From cd6b3a9065c437049f66b511750dbed5029d9125 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 16:23:43 +0100 Subject: [PATCH 02/28] [scroll-animations-1] Add scroll() examples --- scroll-animations-1/Overview.bs | 83 ++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 8821c25417fe..be3349bc2d7b 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -239,10 +239,89 @@ spec:selectors-4; type:dfn; text:selector (which functions as its [=scroll container=]).
- Creation of an anonymous [=Scroll progress timeline=] with ''scroll()'' + Consider the following style sheet and markup: ```css - // TODO + @keyframes grow { + to { scale: 2; } + } + + .subject { + animation: grow linear both; + /* Use an anonymous scroll progress timeline to drive the animation */ + animation-timeline: scroll(); + } + ``` + + ```html + + … + + +
+ … +
Animation Subject
+ … +
+ + + ``` + + The `.subject`‘s animation is set up to be driven by + an anonymous [=Scroll progress timeline=] created with ''scroll()''. + Because no <> or <> are passed into the function, + the default values of ''nearest'' and ''block'' respectively are used. + + Because `.scroller` is the nearest ancestor [=scroll container=], + this results in the `.scroller` element driving the animation: + as you scroll `.scroller` up and down, the `grow` animations’s progress + moves forwards or backwards in direct response. +
+ +
+ Building on the previous example, changing the 'animation-timeline' + to the following results in + the document viewport driving the animation progress. + + ```css + .subject { + animation: grow linear both; + animation-timeline: scroll(root); + } + ``` +
+ +
+ The following declarations for 'animation-timeline' are all equivalent + but some are more explicit about what to target: + + ```css + /* These all are equivalent */ + animation-timeline: scroll(); + animation-timeline: scroll(block); + animation-timeline: scroll(nearest); + animation-timeline: scroll(block nearest); + animation-timeline: scroll(nearest block); + ``` + + This is because the default values for <> and <> + are ''nearest'' and ''block'' respectively. +
+ +
+ To animate the scroller itself, use the ''self'' keyword as the <> + + ```css + @keyframes change-color { + from { color: black; } + to { color: hotpink; } + } + + .subject { + animation: change-color linear both; + /* Use an anonymous scroll progress timeline to drive the animation */ + animation-timeline: scroll(self); + } ```
From 247ac1f6fa45b6f292a38da3a52a69cd7ddcba53 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 16:23:51 +0100 Subject: [PATCH 03/28] [scroll-animations-1] Add ScrollTimeline examples --- scroll-animations-1/Overview.bs | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index be3349bc2d7b..8a6f58f13921 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -423,10 +423,45 @@ spec:selectors-4; type:dfn; text:selector are both computed when either is requested or updated.
- Example with {{ScrollTimeline}} + In the following example, {{ScrollTimeline}} instance that tracks + the document viewport in the block direction is created: ```js - // TODO + const myTimeline = new ScrollTimeline({ + source: document.documentElement, + }); + ``` + + The created {{ScrollTimeline}} instance can be used + to animate an element as follows: + + ```js + const progressbar = document.querySelector('#progress'); + + progressbar.animate( + { + transform: ['scaleX(0)', 'scaleX(1)'], + }, + { + fill: 'forwards', + timeline: myTimeline, + } + ); + ``` +
+ +
+ In this example, the `.scroller` element is the element + whose scroll position drives the progress of the timeline. + The timeline is set to track the scroll offset in the inline direction. + + ```js + const scroller = document.querySelector('.scroller'); + + const myTimeline = new ScrollTimeline({ + source: scroller, + axis: 'inline', + }); ```
From bd6c1a2a2afd3d112583d89f9684c5f11fdc873a Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 16:41:38 +0100 Subject: [PATCH 04/28] [scroll-animations-1] Add scroll-timeline-* examples --- scroll-animations-1/Overview.bs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 8a6f58f13921..6e219f735ba9 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -480,10 +480,22 @@ spec:selectors-4; type:dfn; text:selector See [[css-values-4#linked-properties]].
- Creation of a [=named scroll progress timeline=]: + In the following example the `.subject`’s animation is driven by + the [=named scroll progress timeline=] named `my-scroller`. + This timeline is created on its `.scroller` parent and is set up to + measure progress along the ''inline'' <>: ```css - // TODO + .scroller { + scroll-timeline-name: my-scroller; + scroll-timeline-axis: inline; + } + + .scroller .subject { + animation: grow linear both; + /* Use the 'my-scroller' scroll progress timeline to drive the animation */ + animation-timeline: my-scroller; + } ```
@@ -536,6 +548,23 @@ spec:selectors-4; type:dfn; text:selector 'scroll-timeline-name' and 'scroll-timeline-axis' in a single declaration. +
+ The following two rules are equivalent: + + ```css + .scroller { + scroll-timeline-name: my-scroller; + scroll-timeline-axis: inline; + } + ``` + + ```css + .scroller { + scroll-timeline: my-scroller inline; + } + ``` +
+ # View Progress Timelines # {#view-timelines} Often animations are desired to start and end From daf2409f74825a8c991c0e2a4805db9dab5682a9 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:11:28 +0100 Subject: [PATCH 05/28] [scroll-animations-1] Add view() example --- scroll-animations-1/Overview.bs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 6e219f735ba9..d5275eecd88e 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -728,11 +728,22 @@ spec:selectors-4; type:dfn; text:selector as defined for 'view-timeline-inset'.
- Creation of an anonymous [=View progress timeline=] with ''view()'': + In the following example, each child of the `.scroller` element + will reveal itself as it crosses the scrollport. ```css - // TODO + @keyframes reveal { + from { opacity: 0; } + } + + .scroller > * { + animation: reveal linear both; + animation-timeline: view(); + } ``` + + Because no arguments are passed into ''view()'' it will use the default values + of ''block'' for the <> and ''auto'' for <<'view-timeline-inset'>>.
Each use of ''view()'' corresponds to its own instance of {{ViewTimeline}} From 5c6dd88b9492129cd97b5dc1397d88a98fc24485 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:13:54 +0100 Subject: [PATCH 06/28] [scroll-animations-1] Add ViewTimeline example --- scroll-animations-1/Overview.bs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index d5275eecd88e..adde8f90f997 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -857,10 +857,23 @@ spec:selectors-4; type:dfn; text:selector are all computed when any of them is requested or updated.
- Example with {{ViewTimeline}} + In the following example, each child of the `.scroller` element + will reveal itself as it crosses the scrollport. ```js - // TODO + document.querySelectorAll('.scroller > *').forEach(childElement => { + const timeline = new ViewTimeline({ + subject: childElement, + axis: 'block', + }); + + childElement.animate({ + opacity: [ 0, 1 ], + }, { + fill: 'both', + timeline, + }); + }); ```
From 0ebcf9a4875ef495483d7b60fcb248789f8c2ead Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:43:41 +0100 Subject: [PATCH 07/28] [scroll-animations-1] Add view-timeline-* example --- scroll-animations-1/Overview.bs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index adde8f90f997..068997752b7d 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -892,10 +892,24 @@ spec:selectors-4; type:dfn; text:selector See [[css-values-4#linked-properties]].
- Creation of a [=named view progress timeline=]: + In the following example, each child of the `.scroller` element + will reveal itself as it crosses the scrollport. + This is done by explicitly referring to + the [=named view progress timeline=] created on the `.scroller`: ```css - // TODO + @keyframes reveal { + from { opacity: 0; } + } + + .scroller { + view-timeline: my-scroller block; + } + + .scroller > * { + animation: reveal linear both; + animation-timeline: my-scroller; + } ```
From 35e74ca2d109591491c3f1cd878dbf1f237affcd Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:44:02 +0100 Subject: [PATCH 08/28] [scroll-animations-1] Add animation-range examples --- scroll-animations-1/Overview.bs | 71 +++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 068997752b7d..d31c9cac9229 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -1000,19 +1000,82 @@ spec:selectors-4; type:dfn; text:selector (see [[#named-range-animation-declaration]]).
- Example of a [=named scroll progress timeline=]: + In the following example each child of the `.scroller` element + reveals itself as it enters the scrollport instead of when entirely crossing it. + + This is achieved by setting 'animation-range' to limit the [=active interval=] + to the ''entry'' range: ```css - // TODO + @keyframes reveal { + from { opacity: 0; } + } + + .subject { + animation: reveal linear both; + animation-timeline: view(); + animation-range: entry; + } ```
- Example of a {{ViewTimeline}}: + A variation of the previous example is to add both entry and exit effects, + each linked to their own 'animation-range': ```css - // TODO + @keyframes reveal { + from { opacity: 0; } + } + @keyframes hide { + to { opacity: 0; } + } + + .scroller > * { + animation: reveal linear both, + hide linear forwards; + animation-timeline: view(); + animation-range: entry, exit; + } ``` + + The `reveal` effect is linked to the ''entry'' range + while the `hide` effect is linked to the ''exit'' range. +
+ +
+ The Web Animations API equivalent of the previous example is the following: + + ```js + document.querySelectorAll('.scroller > *').forEach(childElement => { + const timeline = new ViewTimeline({ + subject: childElement, + axis: 'block', + }); + + // Reveal effect on entry + childElement.animate({ + opacity: [ 0, 1 ], + }, { + fill: 'forwards', + timeline, + rangeStart: 'entry 0%', + rangeEnd: 'entry 100%', + }); + + // Hide effect on exit + childElement.animate({ + opacity: [ 1, 0 ], + }, { + fill: 'forwards', + timeline, + rangeStart: 'exit 100%', + rangeEnd: 'exit 100%', + }); + }); + ``` + + Each element gets its own timeline which is used by both effects.
Time-based delays ('animation-delay') From bcfa235a920a6110e2d024e39cf36f46f690ac09 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:50:00 +0100 Subject: [PATCH 09/28] [scroll-animations-1] Add @keyframes example --- scroll-animations-1/Overview.bs | 45 ++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index d31c9cac9229..10403801dfa2 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -1330,8 +1330,51 @@ spec:selectors-4; type:dfn; text:selector at or earlier than 0% or at or after 100% (respectively).
+ In this example the range information is included directly in the ''@keyframes'' rule: + ```css - // TODO + @keyframes animate-in-and-out { + entry 0% { + opacity: 0; transform: translateY(100%); + } + entry 100% { + opacity: 1; transform: translateY(0); + } + + exit 0% { + opacity: 1; transform: translateY(0); + } + exit 100% { + opacity: 0; transform: translateY(-100%); + } + } + + .scroller > * { + animation: linear animate-in-and-out; + animation-timeline: view(); + } + ``` + + It has the same outcome as the following snippet which uses + two distinct sets of keyframes combined with 'animation-range' + + ```css + @keyframes animate-in { + 0% { opacity: 0; transform: translateY(100%); } + 100% { opacity: 1; transform: translateY(0); } + } + + @keyframes animate-out { + 0% { opacity: 1; transform: translateY(0); } + 100% { opacity: 0; transform: translateY(-100%); } + } + + .scroller > * { + animation: animate-in linear forwards, + animate-out linear forwards; + animation-timeline: view(); + animation-range: entry, exit; + } ```
From f066f8e449fd15df21d5f37e1d869cb126850a44 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 30 Dec 2024 17:58:28 +0100 Subject: [PATCH 10/28] [scroll-animations-1] Add animation-range example that uses calc() --- scroll-animations-1/Overview.bs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 10403801dfa2..c1583f26bed4 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -1467,8 +1467,15 @@ spec:selectors-4; type:dfn; text:selector
+ Because <<'animation-range-start'>> and <<'animation-range-end'>> accept <>s, + it’s perfectly fine to do calculations using ''calc()'' for the ranges: + ```css - // TODO: EXAMPLE with <> + #subject { + animation: anim linear both; + animation-timeline: view(); + animation-range: entry calc(100% - 100px) exit calc(0% + 100px); + } ```
From 118da6393700536f24cbcd190bb7bbdebd787e55 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 8 Jan 2025 08:56:21 +0100 Subject: [PATCH 11/28] Update scroll-animations-1/Overview.bs Co-authored-by: fantasai --- scroll-animations-1/Overview.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index c1583f26bed4..0ed3fdc95638 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -423,8 +423,9 @@ spec:selectors-4; type:dfn; text:selector are both computed when either is requested or updated.
- In the following example, {{ScrollTimeline}} instance that tracks - the document viewport in the block direction is created: + In the following example, a {{ScrollTimeline}} instance + that tracks the document viewport in the block direction + is created: ```js const myTimeline = new ScrollTimeline({ From b6e993c42d94df6551750159d0aceafc4c98ada6 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 8 Jan 2025 08:56:41 +0100 Subject: [PATCH 12/28] Update scroll-animations-1/Overview.bs Co-authored-by: fantasai --- scroll-animations-1/Overview.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 0ed3fdc95638..b6954022643f 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -454,7 +454,7 @@ spec:selectors-4; type:dfn; text:selector
In this example, the `.scroller` element is the element whose scroll position drives the progress of the timeline. - The timeline is set to track the scroll offset in the inline direction. + The timeline is set to track its scroll offset in the inline direction. ```js const scroller = document.querySelector('.scroller'); From ecc8ca12c728547f7469437d78bfb665320ea50e Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 8 Jan 2025 08:56:54 +0100 Subject: [PATCH 13/28] Update scroll-animations-1/Overview.bs Co-authored-by: fantasai --- scroll-animations-1/Overview.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index b6954022643f..afd1b307e9fd 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -483,7 +483,7 @@ spec:selectors-4; type:dfn; text:selector
In the following example the `.subject`’s animation is driven by the [=named scroll progress timeline=] named `my-scroller`. - This timeline is created on its `.scroller` parent and is set up to + This timeline is created on its `.scroller` ancestor and is set up to measure progress along the ''inline'' <>: ```css From ed841928eab5e9104f34af35a42e65923eef8770 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 8 Jan 2025 08:57:03 +0100 Subject: [PATCH 14/28] Update scroll-animations-1/Overview.bs Co-authored-by: fantasai --- scroll-animations-1/Overview.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index afd1b307e9fd..f824dd555bf4 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -484,7 +484,7 @@ spec:selectors-4; type:dfn; text:selector In the following example the `.subject`’s animation is driven by the [=named scroll progress timeline=] named `my-scroller`. This timeline is created on its `.scroller` ancestor and is set up to - measure progress along the ''inline'' <>: + measure progress along the [=inline axis=]: ```css .scroller { From 5a3b4ea9b886502064338fc403311c01455712a0 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 20 Jan 2025 14:12:38 +0100 Subject: [PATCH 15/28] [scroll-animations-1] Rework example use non-layout/scrolloffset affecting properties --- scroll-animations-1/Overview.bs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index f824dd555bf4..180fc580eb0f 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -242,12 +242,13 @@ spec:selectors-4; type:dfn; text:selector Consider the following style sheet and markup: ```css - @keyframes grow { - to { scale: 2; } + @keyframes change-background { + from { background-color: aliceblue; } + to { background-color: cornflowerblue; } } .subject { - animation: grow linear both; + animation: change-background linear both; /* Use an anonymous scroll progress timeline to drive the animation */ animation-timeline: scroll(); } @@ -274,7 +275,7 @@ spec:selectors-4; type:dfn; text:selector Because `.scroller` is the nearest ancestor [=scroll container=], this results in the `.scroller` element driving the animation: - as you scroll `.scroller` up and down, the `grow` animations’s progress + as you scroll `.scroller` up and down, the subject’s animations progress moves forwards or backwards in direct response.
@@ -285,7 +286,7 @@ spec:selectors-4; type:dfn; text:selector ```css .subject { - animation: grow linear both; + animation: change-background linear both; animation-timeline: scroll(root); } ``` From 975b3dcdd327339930be25adf93f7976a268d2c5 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 20 Jan 2025 14:22:43 +0100 Subject: [PATCH 16/28] [scroll-animations-1] Add clarification to scroll() example --- scroll-animations-1/Overview.bs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 180fc580eb0f..b49ec9e8eed2 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -277,6 +277,11 @@ spec:selectors-4; type:dfn; text:selector this results in the `.scroller` element driving the animation: as you scroll `.scroller` up and down, the subject’s animations progress moves forwards or backwards in direct response. + + This results in the `background-color` to be + `aliceblue` when at the start of the scroller + and `cornflowerblue` when scrolled to the very end. + Intermediary scroll positions results in an interpolated value.
From 23c716aaddae8baabd9f5627f8d6d27a42c12b54 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 20 Jan 2025 15:13:27 +0100 Subject: [PATCH 17/28] [scroll-animations-1] Add clarification about view() creating unique instances per match --- scroll-animations-1/Overview.bs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index b49ec9e8eed2..e90b0f3b1191 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -735,7 +735,7 @@ spec:selectors-4; type:dfn; text:selector as defined for 'view-timeline-inset'.
- In the following example, each child of the `.scroller` element + In the following example, each direct child of the `.scroller` element will reveal itself as it crosses the scrollport. ```css @@ -749,8 +749,21 @@ spec:selectors-4; type:dfn; text:selector } ``` - Because no arguments are passed into ''view()'' it will use the default values - of ''block'' for the <> and ''auto'' for <<'view-timeline-inset'>>. + For every element matched by the selector, + a [=view progress timeline=] gets created to drive the animation. + Because no arguments are passed into ''view()'' it uses the default values + for <> and <<'view-timeline-inset'>>, + resulting in the scroller being tracked in the ''block'' direction. + + With the keyframes driven by the [=view progress timeline=], + the element will be at `opacity: 0` when it is about to enter the scrollport, + and at `opacity: 1` when it has just left the scrollport. + Any scroll position in between results in an interpolated value. + + Note: Because matched elements + can be positioned at different offsets within the scroller + or can differ in size, + every matched element gets its own unique [=view progress timeline=].
Each use of ''view()'' corresponds to its own instance of {{ViewTimeline}} From bcb41e4a83aeeb3d01ebde5866847cf6c43170e5 Mon Sep 17 00:00:00 2001 From: Bramus Date: Mon, 20 Jan 2025 15:13:52 +0100 Subject: [PATCH 18/28] [scroll-animations-1] Move animation-range examples to the relevant section --- scroll-animations-1/Overview.bs | 160 ++++++++++++++++---------------- 1 file changed, 81 insertions(+), 79 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index e90b0f3b1191..658aa5f3adbf 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -1019,85 +1019,6 @@ spec:selectors-4; type:dfn; text:selector can also be further restricted to a particular timeline range (see [[#named-range-animation-declaration]]). -
- In the following example each child of the `.scroller` element - reveals itself as it enters the scrollport instead of when entirely crossing it. - - This is achieved by setting 'animation-range' to limit the [=active interval=] - to the ''entry'' range: - - ```css - @keyframes reveal { - from { opacity: 0; } - } - - .subject { - animation: reveal linear both; - animation-timeline: view(); - animation-range: entry; - } - ``` -
- -
- A variation of the previous example is to add both entry and exit effects, - each linked to their own 'animation-range': - - ```css - @keyframes reveal { - from { opacity: 0; } - } - @keyframes hide { - to { opacity: 0; } - } - - .scroller > * { - animation: reveal linear both, - hide linear forwards; - animation-timeline: view(); - animation-range: entry, exit; - } - ``` - - The `reveal` effect is linked to the ''entry'' range - while the `hide` effect is linked to the ''exit'' range. -
- -
- The Web Animations API equivalent of the previous example is the following: - - ```js - document.querySelectorAll('.scroller > *').forEach(childElement => { - const timeline = new ViewTimeline({ - subject: childElement, - axis: 'block', - }); - - // Reveal effect on entry - childElement.animate({ - opacity: [ 0, 1 ], - }, { - fill: 'forwards', - timeline, - rangeStart: 'entry 0%', - rangeEnd: 'entry 100%', - }); - - // Hide effect on exit - childElement.animate({ - opacity: [ 1, 0 ], - }, { - fill: 'forwards', - timeline, - rangeStart: 'exit 100%', - rangeEnd: 'exit 100%', - }); - }); - ``` - - Each element gets its own timeline which is used by both effects. -
- Time-based delays ('animation-delay') get converted to their respective proportions as described in [[web-animations-2#animations]] @@ -1431,6 +1352,87 @@ spec:selectors-4; type:dfn; text:selector ISSUE: Define application to time-driven animations. +### Examples + +
+ In the following example, each direct child of the `.scroller` element + reveals itself as it enters the scrollport instead of when entirely crossing it. + + This is achieved by setting 'animation-range' to limit the [=active interval=] + to the ''entry'' range instead of the default ''cover'' range: + + ```css + @keyframes reveal { + from { opacity: 0; } + } + + .subject { + animation: reveal linear both; + animation-timeline: view(); + animation-range: entry; + } + ``` +
+ +
+ A variation of the previous example is to add both entry and exit effects, + each linked to their own 'animation-range': + + ```css + @keyframes reveal { + from { opacity: 0; } + } + @keyframes hide { + to { opacity: 0; } + } + + .scroller > * { + animation: reveal linear both, + hide linear forwards; + animation-timeline: view(); + animation-range: entry, exit; + } + ``` + + The `reveal` effect is linked to the ''entry'' range + while the `hide` effect is linked to the ''exit'' range. +
+ +
+ The Web Animations API equivalent of the previous example is the following: + + ```js + document.querySelectorAll('.scroller > *').forEach(childElement => { + const timeline = new ViewTimeline({ + subject: childElement, + axis: 'block', + }); + + // Reveal effect on entry + childElement.animate({ + opacity: [ 0, 1 ], + }, { + fill: 'forwards', + timeline, + rangeStart: 'entry 0%', + rangeEnd: 'entry 100%', + }); + + // Hide effect on exit + childElement.animate({ + opacity: [ 1, 0 ], + }, { + fill: 'forwards', + timeline, + rangeStart: 'exit 100%', + rangeEnd: 'exit 100%', + }); + }); + ``` + + Each element gets its own timeline which is used by both effects. +
+ ### Specifying an Animation’s Timeline Range: the 'animation-range' shorthand ### {#animation-range}

From 85b1bc7fa00800fa6d0ba0c4d0edfe598b8a7d9d Mon Sep 17 00:00:00 2001
From: Bramus 
Date: Fri, 31 Jan 2025 02:31:06 +0100
Subject: [PATCH 19/28] Update scroll-animations-1/Overview.bs

---
 scroll-animations-1/Overview.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index bfec8e257f9e..93f35fabeb4d 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -278,7 +278,7 @@ spec:selectors-4; type:dfn; text:selector
 		as you scroll `.scroller` up and down, the subject’s animations progress
 		moves forwards or backwards in direct response.
 
-		This results in the `background-color` to be
+		This results in the `background-color` being
 		`aliceblue` when at the start of the scroller
 		and `cornflowerblue` when scrolled to the very end.
 		Intermediary scroll positions results in an interpolated value.

From db88e249254b7dd5fe07957408be0e3a28aa7ae7 Mon Sep 17 00:00:00 2001
From: Bramus 
Date: Fri, 31 Jan 2025 02:31:13 +0100
Subject: [PATCH 20/28] Update scroll-animations-1/Overview.bs

---
 scroll-animations-1/Overview.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index 93f35fabeb4d..9a3e6dc007ca 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -753,7 +753,7 @@ spec:selectors-4; type:dfn; text:selector
 		a [=view progress timeline=] gets created to drive the animation.
 		Because no arguments are passed into ''view()'' it uses the default values
 		for <> and <<'view-timeline-inset'>>,
-		resulting in the scroller being tracked in the ''block'' direction.
+		thus tracking its scroll position in the [=block axis=].
 		
 		With the keyframes driven by the [=view progress timeline=],
 		the element will be at `opacity: 0` when it is about to enter the scrollport,

From 5690e1dd107faef873316db29e01bdf18576d68d Mon Sep 17 00:00:00 2001
From: Bramus 
Date: Fri, 7 Feb 2025 15:44:46 +0100
Subject: [PATCH 21/28] Fix selector in example

---
 scroll-animations-1/Overview.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index 9a3e6dc007ca..c17a3b32be36 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -1366,7 +1366,7 @@ spec:selectors-4; type:dfn; text:selector
 			from { opacity: 0; }
 		}
 
-		.subject {
+		.scroller > * {
 			animation: reveal linear both;
 			animation-timeline: view();
 			animation-range: entry;

From cbeeaf6c6ff6a2666c41f7d439070339499917bb Mon Sep 17 00:00:00 2001
From: Bramus 
Date: Fri, 7 Feb 2025 15:44:58 +0100
Subject: [PATCH 22/28] Make example keyframes more explicit

---
 scroll-animations-1/Overview.bs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index c17a3b32be36..4325cd48eb08 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -1381,8 +1381,10 @@ spec:selectors-4; type:dfn; text:selector
 		```css
 		@keyframes reveal {
 			from { opacity: 0; }
+			to { opacity: 1; }
 		}
 		@keyframes hide {
+			from { opacity: 1; }
 			to { opacity: 0; }
 		}
 

From 3aa5d01dff14d8a2690c40ad00d02ccdbddacb65 Mon Sep 17 00:00:00 2001
From: Bramus 
Date: Fri, 7 Feb 2025 15:51:28 +0100
Subject: [PATCH 23/28] Clarify the visual outcome of certain examples

---
 scroll-animations-1/Overview.bs | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index 4325cd48eb08..de999513cd75 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -1372,6 +1372,12 @@ spec:selectors-4; type:dfn; text:selector
 			animation-range: entry;
 		}
 		```
+
+		In a vertical scroller, this results in an element going fully transparent (`opacity: 0`)
+		when its about to enter the scroller from the bottom edge of the scroller
+		to being fully opaque (`opacity: 1`) when it has completely entered the scroller.
+
+		Scroll positions in between result in an opacity `0` and `1`.
 	
@@ -1398,6 +1404,14 @@ spec:selectors-4; type:dfn; text:selector The `reveal` effect is linked to the ''entry'' range while the `hide` effect is linked to the ''exit'' range. + + In a vertical scroller, when scrolling down, + this results in the element going from `opacity: 0` to `opacity: 1` + as it enters the scrollport from the bottom edge of the scroller. + + When continuing to scroll down, + the element will eventually go from `opacity: 1` to `opacity: 0` + as the subject exits the scrollport at the top edge of the scroller.
@@ -1432,7 +1446,21 @@ spec:selectors-4; type:dfn; text:selector }); ``` - Each element gets its own timeline which is used by both effects. + For every matched element, a single timeline tracking that element is created. + The timeline tracks the element inside its scroller in the block direction. + + The timeline is used to drive two animations added to the element + but the effects are only attached to a part of the range, + thanks to the `rangeStart` and `rangeEnd` options. + + The first animation is attached to the ''entry'' range, + animating the element from `opacity: 0` to `opacity: 1` + as it enters the scrollport. + + The second animation is attached to the ''exit'' range, + animating the element from `opacity: 1` to `opacity: 0` + as it leaves the scrollport. +
### Specifying an Animation’s Timeline Range: the 'animation-range' shorthand ### {#animation-range} From 0ef342217752855d769f38ea275d1ed89f91122b Mon Sep 17 00:00:00 2001 From: Bramus Date: Sat, 8 Feb 2025 19:58:21 +0100 Subject: [PATCH 24/28] Add more descriptions --- scroll-animations-1/Overview.bs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index f509d9fdf41f..aa853da42ce5 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -456,6 +456,10 @@ spec:selectors-4; type:dfn; text:selector } ); ``` + + This makes the targeted `#progress` element + animate from a `scaleX(0)` transform when at the top of the page + to a `scaleX(1)` when at the bottom of the page.
@@ -471,6 +475,10 @@ spec:selectors-4; type:dfn; text:selector axis: 'inline', }); ``` + + Scrolling the root scroller has no effect here, + it is only when you scroll the `.scroller` element in the inline direcion + that the animation that uses the timeline will tick.
## Named Scroll Progress Timelines ## {#scroll-timelines-named} From 0a4cbaa4fc8c1b6745c2f3ddb269361693ff2953 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 12 Feb 2025 15:23:44 +0100 Subject: [PATCH 25/28] Add more descriptions --- scroll-animations-1/Overview.bs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index aa853da42ce5..ee943fc0b33f 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -904,6 +904,12 @@ spec:selectors-4; type:dfn; text:selector }); }); ``` + + In a vertical scroller, this results in an element going fully transparent (`opacity: 0`) + when its about to enter the scroller from the bottom edge of the scroller + to being fully opaque (`opacity: 1`) when it has completely entered the scroller. + + Scroll positions in between result in an opacity `0` and `1`. ## Named View Progress Timelines ## {#view-timelines-named} @@ -921,10 +927,14 @@ spec:selectors-4; type:dfn; text:selector See [[css-values-4#linked-properties]].
- In the following example, each child of the `.scroller` element - will reveal itself as it crosses the scrollport. - This is done by explicitly referring to - the [=named view progress timeline=] created on the `.scroller`: + This example behaves exactly the same + as the previous one: + each child of the `.scroller` element will reveal itself + as it crosses the scrollport. + + The difference is that + instead of using an anonymous [=View progress timeline=] + to drive the animation, it now uses a [=named view progress timeline=] that tracks the `.scroller`. ```css @keyframes reveal { From 7c414ce987d31216d5caccda36f19aa5be74da41 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 12 Feb 2025 15:24:51 +0100 Subject: [PATCH 26/28] Timeline names are s --- scroll-animations-1/Overview.bs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index ee943fc0b33f..fb25a64f5321 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -503,14 +503,14 @@ spec:selectors-4; type:dfn; text:selector ```css .scroller { - scroll-timeline-name: my-scroller; + scroll-timeline-name: --my-scroller; scroll-timeline-axis: inline; } .scroller .subject { animation: grow linear both; /* Use the 'my-scroller' scroll progress timeline to drive the animation */ - animation-timeline: my-scroller; + animation-timeline: --my-scroller; } ```
@@ -569,14 +569,14 @@ spec:selectors-4; type:dfn; text:selector ```css .scroller { - scroll-timeline-name: my-scroller; + scroll-timeline-name: --my-scroller; scroll-timeline-axis: inline; } ``` ```css .scroller { - scroll-timeline: my-scroller inline; + scroll-timeline: --my-scroller inline; } ``` @@ -942,12 +942,12 @@ spec:selectors-4; type:dfn; text:selector } .scroller { - view-timeline: my-scroller block; + view-timeline: --my-scroller block; } .scroller > * { animation: reveal linear both; - animation-timeline: my-scroller; + animation-timeline: --my-scroller; } ``` @@ -1118,19 +1118,19 @@ spec:selectors-4; type:dfn; text:selector } .root { - /* declares the scope of a 'scroller' timeline to reach all descendants */ - timeline-scope: scroller; + /* declares the scope of a '--scroller' timeline to reach all descendants */ + timeline-scope: --scroller; } .root .animation { animation: anim; - /* references the 'scroller' timeline for driving the progress of 'anim' */ - animation-timeline: scroller; + /* references the '--scroller' timeline for driving the progress of 'anim' */ + animation-timeline: --scroller; } .root .animation + .scroller { - /* attaches a scroll progress timeline to the timeline name 'scroller' */ - scroll-timeline: scroller; + /* attaches a scroll progress timeline to the timeline named '--scroller' */ + scroll-timeline: --scroller; } … From 7b8321f3f8a4f4706f328973de12a437bced9b82 Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 12 Feb 2025 15:26:18 +0100 Subject: [PATCH 27/28] More rename --- scroll-animations-1/Overview.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index fb25a64f5321..02bef7fad7bc 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -497,7 +497,7 @@ spec:selectors-4; type:dfn; text:selector
In the following example the `.subject`’s animation is driven by - the [=named scroll progress timeline=] named `my-scroller`. + the [=named scroll progress timeline=] named `--my-scroller`. This timeline is created on its `.scroller` ancestor and is set up to measure progress along the [=inline axis=]: @@ -509,7 +509,7 @@ spec:selectors-4; type:dfn; text:selector .scroller .subject { animation: grow linear both; - /* Use the 'my-scroller' scroll progress timeline to drive the animation */ + /* Use the '--my-scroller' scroll progress timeline to drive the animation */ animation-timeline: --my-scroller; } ``` From ad1ac776b072a669023ce324d9429c8b450f71ac Mon Sep 17 00:00:00 2001 From: Bramus Date: Wed, 12 Feb 2025 15:29:48 +0100 Subject: [PATCH 28/28] More detailed explanation for named scroll-timeline example --- scroll-animations-1/Overview.bs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs index 02bef7fad7bc..676e451c39cb 100644 --- a/scroll-animations-1/Overview.bs +++ b/scroll-animations-1/Overview.bs @@ -513,6 +513,10 @@ spec:selectors-4; type:dfn; text:selector animation-timeline: --my-scroller; } ``` + + As you scroll horizontally through the `.scroller` element, + the `grow` animation on the contained `.subject` element + will move forwards or backwards in direct response.
### Naming a Scroll Progress Timeline: the 'scroll-timeline-name' property ### {#scroll-timeline-name}