animation-trigger CSS property
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The animation-trigger CSS property specifies whether CSS animations declared on an element are triggered animations (or not) and, if so, what their triggers are and how they should behave when the trigger becomes active or inactive. This can be used to create scroll-triggered animations.
Syntax
/* Keywords */
animation-trigger: none;
/* One trigger */
animation-trigger: --my-trigger play;
animation-trigger: --my-other-trigger play-once;
animation-trigger: --my-trigger play-forwards play-backwards;
animation-trigger: --my-other-trigger play reset;
/* Multiple values */
animation-trigger:
none,
-forwards play-backwards,
--my-other-trigger play reset;
/* Global values */
animation-trigger: inherit;
animation-trigger: initial;
animation-trigger: revert;
animation-trigger: revert-layer;
animation-trigger: unset;
Values
Specified as a comma-separated list of values. Each value is either the keyword none or a <dashed-ident> followed by one or two <animation-action> values.
none-
The associated animation is not a triggered animation.
<dashed-ident>-
A custom identifier defining the name of the trigger that will trigger the animation.
<animation-action>-
An
<animation-action>: The keywordsnone,play,play-forwards,play-backwards,play-once,pause,replay, orreset.
Description
The animation-trigger property specifies which trigger will control an animated element's animations. A value other than none turns the animation into a scroll-triggered animation.
Defining a trigger
The trigger is identified via a <dashed-ident> value, which is defined in the tracked element's timeline-trigger-name property.
For example:
.animated {
animation: rotate 3s infinite linear both;
animation-trigger: --my-trigger play;
}
In this case, the animation will play when an element with a timeline-trigger-name of --my-trigger enters the activation range defined on the trigger.
Here we create a trigger by setting the timeline-trigger-name using the timeline-trigger shorthand property. The .trigger can be any element, including the .animated element.
.trigger {
timeline-trigger: --my-trigger view();
}
If an element has an animation and an animation-trigger set on it, but no scrolling element exists with the same <dashed-ident> set as its timeline-trigger-name value, the animation will not have a trigger and therefore will never play.
Defining the triggered animation actions
The animation-trigger value must include one or two <animation-action> keywords after the <dashed-ident> to specify the behavior of the animation when the trigger is activated and deactivated. If two <animation-action>s are specified, the first is the activation action and the second is the deactivation action. If only one <animation-action> is set, this is the activation action, and there is no deactivation.
For example:
.animated {
animation: rotate 3s infinite linear both;
animation-trigger: --my-trigger play-forwards play-backwards;
}
When the trigger is activated, the animation will play-forwards. When the trigger is deactivated, the animation will play-backwards.
There are eight <animation-action> values, each providing different animation behaviors.
Setting play-forwards play-backwards is a common pattern, often used to "animate in" an element when its trigger becomes active, such as by scrolling into view, and then "animate out" the element again when the trigger becomes inactive, for example, by scrolling out of view.
The play-once action is generally used on its own or as part of play-once pause; setting play-once as the activation action causes the animation to play only once when it scrolls into view. The addition of pause on deactivation pauses the animation when the trigger scrolls out of its activation range, restarting from where it was paused if re-activated.
See the <animation-action> data type for examples and more about each keyword value.
Triggering the same animation via multiple different triggers
If you have an animated element, and you want to define triggers on multiple different elements that all trigger the same animation, you need to specify the animation multiple times on the animated element, giving each animation instance a different trigger.
For example:
.animated {
animation:
moveright 2s 1 ease-out both,
moveright 2s 1 ease-out forwards;
animation-trigger:
--t1 play-forwards play-backwards,
--t2 play-forwards play-backwards;
}
.trigger1 {
timeline-trigger: --t1 view();
}
.trigger2 {
timeline-trigger: --t2 view();
}
See Multiple triggers for the same animation for a working example.
Resetting via the animation shorthand
The animation-trigger property is a reset-only sub-property of the animation shorthand property. This means that trigger names and animation actions can not be included in the animation shorthand, but setting the animation shorthand resets animation-trigger to its initial value of none. For this reason, you should always set animation-trigger after a corresponding animation property in a declaration list or declare the animation-trigger in a declaration block with selectors with stronger specificity.
Multiple animation-trigger values
The animation-trigger property works in the same way as the animation shorthand property and the other animation longhand properties concerning setting multiple values:
- If multiple
animation-namevalues are set, but only a singleanimation-triggervalue is set, theanimation-triggerwill apply to all the animations. - If two or more comma-separated
animation-triggervalues are set, they will cycle between the animations until all of them have ananimation-triggervalue set. See an example of declaring multiple scroll-triggered animations.
Given the following CSS:
.animated {
animation:
fade-in linear 1s forwards,
rotate infinite 5s both,
shrink ease-in 3s forwards,
colorchange steps(5) 5s forwards;
animation-trigger:
--t1 play pause,
--t2 forwards backwards;
}
.trigger1 {
timeline-trigger: --t1 view();
}
.trigger2 {
timeline-trigger: --t2 view();
}
With animation-trigger: --t1 play pause, --t2 forwards backwards set on the animated element, --t1 will trigger the fade-in and shrink animations while --t2 will trigger the rotate and colorchange animations.
Formal definition
| Initial value | none |
|---|---|
| Applies to | all elements |
| Inherited | no |
| Computed value | as specified |
| Animation type | Not animatable |
Formal syntax
animation-trigger =
[ none | [ <dashed-ident> <animation-action>+ ]+ ]#
Examples
>Basic usage
This example demonstrates how to create a scroll-triggered animation that plays when activated and pauses when deactivated.
HTML
The markup contains two <div> elements, one to animate and one on which to create a trigger, plus some basic text content to cause the page to scroll. The text is hidden 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 the animation plays and pauses.
.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 both;
animation-trigger: --t play pause;
}
The .trigger element creates the animated element's trigger with a timeline-trigger-name of --t. This value is the identifier referenced in the .animated declaration block's animation-trigger property value, associating the two together. We also include a timeline-trigger-source value of view(), which sets the timeline trigger as a view progress timeline. We could have declared both together as timeline-trigger: view() --t.
.trigger {
timeline-trigger-name: --t;
timeline-trigger-source: view();
}
Result
Try scrolling the content up and down. When any part of the .trigger appears in the scrollport, the animation will play; when it has completely left the scrollport at either edge, the animation will pause.
Making the animated element create the trigger
In this example, we demonstrate how an animated element can also create its own trigger.
HTML
This time, the markup contains only a single <div> element, plus basic text content to cause the page to scroll. We have hidden the content markup for brevity.
<div>I create my own trigger</div>
CSS
The <div> element has an animation applied that smoothly inverts its colors, defined as follows:
@keyframes invert-colors {
from {
background: orange;
color: black;
}
to {
background: black;
color: orange;
}
}
We set an animation-trigger value on the <div> that references a timeline-trigger-name of --t. We include two <animation-action> values — play-forwards and play-backwards — which specify that the animation will play forwards on activation and play in reverse on deactivation.
We also specify a timeline-trigger value of --t view() contain on the <div>, so the <div> creates the trigger for its own animation. The timeline-trigger shorthand includes three longhand property values:
- A
timeline-trigger-namevalue: A<dashed-ident>identifier referenced in theanimation-triggerproperty. - A
timeline-trigger-sourcevalue: Theview()value sets the timeline trigger to a view progress timeline tracking the element inside its nearest scrolling ancestor element. - A
timeline-trigger-activation-rangevalue: The<timeline-range-name>valuecontainrepresents the range of a view progress timeline where the subject element is fully contained by, or fully contains, the view progress visibility range within the scrollport. This means the trigger will activate when the<div>is fully inside the scrollport, and deactivate when it starts to exit the scrollport. See Understanding timeline range names for more information.
Because we didn't set a value for the timeline-trigger-active-range component, the active range is the same as the activation range.
div {
animation: invert-colors 0.6s ease-in both;
animation-trigger: --t play-forwards play-backwards;
timeline-trigger: --t view() contain;
}
Result
Try scrolling the content up. When the <div> fully appears in the scrollport, its animation will play; when any part of the <div> leaves the scrollport at either edge, the animation will play backwards.
Multiple triggers for the same animation
This example shows how to assign multiple triggers to control the same animation. This example is similar to the basic usage example, but with multiple triggers triggering the same keyframe animation.
HTML
We include three <div> elements as triggers. The text content is hidden for brevity.
<div class="animated">I am animated</div>
...
<div class="trigger1">I create a trigger</div>
...
<div class="trigger2">I create another trigger</div>
...
<div class="trigger3">I create yet another trigger</div>
...
CSS
The value of the animation shorthand property is a comma-separated list of animations, applying the same rotate keyframe animation three times. The animation-trigger value is a comma-separated list of three animation triggers, one for each animation instance.
.animated {
animation:
rotate 3s infinite linear both,
rotate 3s infinite linear forwards,
rotate 3s infinite linear forwards;
animation-trigger:
--t1 play-forwards play-backwards,
--t2 play-forwards play-backwards,
--t3 play-forwards play-backwards;
}
We define a timeline trigger with a different name on each trigger <div> element. These names correspond to the names referenced in the .animated element's animation-trigger property.
.trigger1 {
timeline-trigger: --t1 view();
}
.trigger2 {
timeline-trigger: --t2 view();
}
.trigger3 {
timeline-trigger: --t3 view();
}
Result
Try scrolling the content up and down, and note how the animation is activated and then deactivated when each trigger element scrolls into and out of view.
Specifications
| Specification |
|---|
| Animation Triggers> # propdef-animation-trigger> |
Browser compatibility
See also
<animation-action>typetimeline-trigger-name,timeline-trigger-source,timeline-trigger-activation-range, andtimeline-trigger-active-rangetimeline-triggershorthandtrigger-scope- Using CSS scroll-triggered animations
- CSS animation triggers module
- CSS animations module
- CSS scroll-driven animations module