timeline-trigger CSS property
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The timeline-trigger CSS shorthand property defines a scroll-triggered animation trigger on an element.
Constituent properties
This property is a shorthand for the following CSS properties:
Syntax
/* Keyword */
timeline-trigger: none;
/* name | source */
timeline-trigger: --t view();
timeline-trigger: --t --my-timeline;
/* name | source | activation range */
timeline-trigger: --t view() contain;
timeline-trigger: --t view() entry exit 50%;
/* name | source | activation range | active range */
timeline-trigger: --t view() contain / cover;
timeline-trigger: --t view() entry / entry exit 50%;
/* Multiple triggers */
timeline-trigger:
--t view(),
--other-trigger --my-timeline entry / entry 50% exit 50%;
/* Global values */
timeline-trigger: inherit;
timeline-trigger: initial;
timeline-trigger: revert;
timeline-trigger: revert-layer;
timeline-trigger: unset;
Values
Specified as a space-separated list of the constituent timeline trigger property values, or the keyword none.
none-
Specifies that the element does not create a trigger, resetting all four longhand properties to their default values.
<'timeline-trigger-name'>-
A
timeline-trigger-namevalue representing the trigger's identifying name. Defaults tonone. <'timeline-trigger-source'>-
A
timeline-trigger-sourcevalue representing the trigger's timeline. Defaults toauto. <'timeline-trigger-activation-range'>Optional-
A
timeline-trigger-activation-rangevalue representing the trigger's activation range. Defaults tonormal, which is equivalent tocover 0% cover 100%for a view progress timelinetimeline-trigger-source, and0% 100%for a scroll progress timelinetimeline-trigger-source. <'timeline-trigger-active-range'>Optional-
A
timeline-trigger-active-rangevalue representing the trigger's activation range. Defaults toauto, which sets the<'timeline-trigger-active-range'>to the same value as the<'timeline-trigger-activation-range'>.
Description
The timeline-trigger property can be used to define all the longhand properties used to create a CSS scroll-triggered animation trigger in a single declaration, resetting those not explicitly set.
A typical example looks like so:
.trigger {
timeline-trigger: --my-trigger view() entry / contain;
}
An element with this declaration set will have:
- An identifying
timeline-trigger-nameof--my-trigger. - A
timeline-trigger-sourcevalue ofview(), which selects the element's nearest ancestor scrolling element to define its timeline trigger. - An activation range of
entry, meaning that the trigger will activate when its tracked element moves into theentryrange. This is the range between the element's start edge crossing the scrollport's end edge, and the element's end edge crossing the scrollport's end edge. - An active range of
containmeaning that once activated, the trigger will stay active until its tracked element leaves thecontainrange: the range in which any part of the tracked element is visible in the scrollport.
An animated element can be triggered by the previously-described trigger by referencing its identifying name in its animation-trigger property. It is possible for the animated element and the element that creates the trigger to be the same element; that is, if a single element has both the timeline-triggerand animation-trigger properties set on it.
The none value
The none keyword specifies that the element does not create a scroll-triggered animation trigger. none is equivalent to setting none auto normal / normal, which effectively resets all four equivalent longhand properties to their default values.
Shorthand property order
Due to the potential for ambiguities in the syntax, this shorthand's values must be given in the specified order.
timeline-trigger-nametimeline-trigger-source- Optionally, a
timeline-trigger-activation-range - A
timeline-trigger-active-rangevalue, preceded by a forward slash.
The timeline-trigger-active-range value can only be included if the timeline-trigger-activation-range value is included.
Formal definition
| Initial value | as each of the properties of the shorthand:
|
|---|---|
| Applies to | all elements |
| Inherited | no |
| Computed value | as each of the properties of the shorthand:
|
| Animation type | as each of the properties of the shorthand:
|
Formal syntax
timeline-trigger =
none |
[ <'timeline-trigger-name'> <'timeline-trigger-source'> <'timeline-trigger-activation-range'> [ / <'timeline-trigger-active-range'> ]? ]#
<timeline-trigger-name> =
none |
<dashed-ident>#
<timeline-trigger-source> =
<single-animation-timeline>#
<timeline-trigger-activation-range> =
[ <'timeline-trigger-activation-range-start'> <'timeline-trigger-activation-range-end'>? ]#
<timeline-trigger-active-range> =
[ <'timeline-trigger-active-range-start'> <'timeline-trigger-active-range-end'>? ]#
<single-animation-timeline> =
auto |
none |
<dashed-ident> |
<scroll()> |
<view()>
<timeline-trigger-activation-range-start> =
[ normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#
<timeline-trigger-activation-range-end> =
[ normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#
<timeline-trigger-active-range-start> =
[ auto | normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#
<timeline-trigger-active-range-end> =
[ auto | normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#
<scroll()> =
scroll( [ <scroller> || <axis> ]? )
<view()> =
view( [ <axis> || <'view-timeline-inset'> ]? )
<length-percentage> =
<length> |
<percentage>
<scroller> =
root |
nearest |
self
<axis> =
block |
inline |
x |
y
<view-timeline-inset> =
[ [ auto | <length-percentage> ]{1,2} ]#
Examples
>Basic usage
In this example, we show how to set up a basic scroll-triggered animation, including defining the trigger using a timeline-trigger shorthand property.
HTML
Our markup contains two <div> elements, one to animate and one on which to create a trigger, and some basic text content to cause the page to scroll.
We have hidden the text content for brevity.
<div class="animated">I am animated</div>
...
<div class="trigger">I create the trigger</div>
...
CSS
The animated <div> element's position is set to fixed, positioning it near the top-left of the scrollport to enable us to see when its animation starts and stops.
.animated {
position: fixed;
top: 25px;
left: 25px;
}
Next, we define the @keyframes for the rotate animation we will use later:
@keyframes rotate {
from {
rotate: 0deg;
}
to {
rotate: 360deg;
}
}
Using the animation shorthand, the .animated element has the rotate animation applied. Without an associated trigger, the element would start animating when the page loads. The animation-trigger property makes it a triggered animation. The value references a timeline-trigger-name of --t and specifies two <animation-action> values — play and pause — which specify that the animation will play on activation, and pause on deactivation.
.animated {
animation: rotate 3s infinite linear;
animation-trigger: --t play pause;
}
The .trigger <div> element creates the animated <div>'s trigger using a timeline-trigger value of --t view() entry / cover. This specifies the following, all in a single declaration:
- A
timeline-trigger-namevalue of--t, which is equal to the identifier referenced in the animated<div>'sanimation-triggerproperty value, associating the two together. - A
timeline-trigger-sourcevalue ofview(), which sets the timeline trigger as a view progress timeline, and the element providing the timeline trigger as the nearest scrolling ancestor element. - A
timeline-trigger-activation-rangeofentry, which means that the trigger will activate in theentryrange (from the point where the tracked element's block start edge enters the scrollport, to the point where its block end edge enters the scrollport). - A
timeline-trigger-active-rangeofcover, which means that, once activated, the trigger will stay active until the tracked element leaves thecoverrange (in other words, until it completely leaves the scrollport).
.trigger {
timeline-trigger: --t view() entry / cover;
}
Result
Try scrolling the content. The rotation will start when the tracked element enters the entry range down the bottom of the scrollport, but won't stop again until it has completely exited the scrollport.
Multiple timeline-trigger values
In this example, we build on the previous example to demonstrate how multiple timeline-trigger values can be set on the same element, creating multiple triggers that can be used to trigger multiple animations.
HTML
The markup for this example is exactly the same as the previous example markup except that we have included one extra animated <div> element with a class of animated2. This example has a total of two animated elements and one element to create triggers on.
CSS
We give the animated elements fixed positioning like in the previous example, but we give them different left values so that they don't sit on top of one another.
.animated,
.animated2 {
position: fixed;
top: 25px;
}
.animated {
left: 25px;
}
.animated2 {
left: 150px;
}
Next, we define the @keyframes for the two animations we'll apply to the <div>s:
@keyframes rotate {
from {
rotate: 0deg;
}
to {
rotate: 360deg;
}
}
@keyframes up-down {
0% {
translate: 0 0;
}
25% {
translate: 0 25px;
}
50% {
translate: 0 0;
}
75% {
translate: 0 -25px;
}
100% {
translate: 0 0;
}
}
The scroll trigger CSS is very similar to the previous example, except that in this case we have separate animation and animation-trigger properties applied to the two animated <div> elements. Each one has a different animation that is triggered by a separate timeline trigger, and different <animation-action> values applied. The first animation plays on activation and plays in reverse on deactivation, whereas the second one plays on activation and pauses on deactivation.
.animated {
animation: rotate 3s infinite linear both;
animation-trigger: --t play-forwards play-backwards;
}
.animated2 {
animation: up-down 1s infinite linear;
animation-trigger: --t2 play pause;
}
We then set a timeline-trigger value on the .trigger <div> that contains two separate values. Each one has a separate timeline-trigger-name and different timeline-trigger-activation-range and timeline-trigger-active-range values so that the two animated elements start and stop their animations at different offsets.
.trigger {
timeline-trigger:
--t view() entry / cover,
--t2 view() contain;
}
Result
Try scrolling the content. The first animated element will start to rotate when the tracked element enters the entry range down at the bottom of the scrollport, and will start to rotate in reverse when the tracked element has completely exited the scrollport. The second animated element will start to move up and down when the tracked element has completely entered the scrollport, and stop when it starts to exit again.
Specifications
| Specification |
|---|
| Animation Triggers> # propdef-timeline-trigger> |