GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||
GeezerVison is showing developer.mozilla.org — animation-trigger CSS property - CSS | MDN animation-trigger CSS property
|
| Initial value | none |
|---|---|
| Applies to | all elements |
| Inherited | no |
| Computed value | as specified |
| Animation type | Not animatable |
animation-trigger =
[ none | [ <dashed-ident> <animation-action>+ ]+ ]#
This example demonstrates how to create a scroll-triggered animation that plays when activated and pauses when deactivated.
The markup contains two <div> elements, one to animate and one to create a trigger, plus some basic text content to make the page scrollable. The text is hidden for brevity.
<div class="animated">I am animated</div>
...
<div class="trigger">I create the trigger</div>
...
<div class="animated">I am animated</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<div class="trigger">I create the trigger</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
The .animated element's position is set to fixed, positioning it near the top-left of the scrollport to allow us to see the animation play and pause.
body {
width: 80%;
margin: 0 auto;
font-family: "Helvetica", "Arial";
font-size: 1.3rem;
}
div {
height: 100px;
border: 5px solid black;
}
.animated {
width: 100px;
background: orange;
}
.trigger {
background: wheat;
}
.animated {
position: fixed;
top: 25px;
left: 25px;
}
Next, we define the @keyframes for the rotate animation:
@keyframes rotate {
from {
rotate: 0deg;
}
to {
rotate: 360deg;
}
}
Using the animation shorthand, the rotate animation is applied to the .animated element. Without an associated trigger, the animation would start 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;
}
We set a timeline-trigger-name of --t on the .trigger element. As this value is the identifier referenced in the .animated declaration block's animation-trigger property value, this associates the two together, creating the animated element's trigger. We also include a timeline-trigger-source value of view(), which sets the timeline trigger as a view progress timeline and both the active and activation ranges as the full cover timeline. We could have declared both together as timeline-trigger: view() --t.
.trigger {
timeline-trigger-name: --t;
timeline-trigger-source: view();
}
Try scrolling the content up and down. When any part of the .trigger element appears in the scrollport, the animation plays; when it has completely left the scrollport at either edge, the animation pauses.
In this example, we demonstrate how an animated element can also create its own trigger.
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>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<div>I create my own trigger</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
We create an @keyframes block that inverts the background and foreground colors:
body {
width: 80%;
margin: 0 auto;
font-family: "Helvetica", "Arial";
font-size: 1.3rem;
}
div {
height: 100px;
background: orange;
border: 5px solid black;
}
@keyframes invert-colors {
from {
background: orange;
color: black;
}
to {
background: black;
color: orange;
}
}
We set the animation on the <div> element, inverting the colors smoothly over 600ms. We also set an animation-trigger value that references a timeline-trigger-name of --t and 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 it creates the trigger for its own animation. The timeline-trigger shorthand includes three longhand property values:
timeline-trigger-name value: A <dashed-ident> identifier referenced in the animation-trigger property.timeline-trigger-source value: The view() value sets the timeline trigger to a view progress timeline tracking the element inside its nearest scrolling ancestor element.timeline-trigger-activation-range value: The <timeline-range-name> value of contain sets the trigger to activate when the <div> is fully inside the scrollport. Because we didn't set a value for the timeline-trigger-active-range component, the active range is the same as the activation range, so it deactivates when it starts to exit the scrollport.div {
animation: invert-colors 0.6s ease-in both;
animation-trigger: --t play-forwards play-backwards;
timeline-trigger: --t view() contain;
}
Try scrolling the content up. When the <div> is fully in the scrollport, its animation plays. When any part leaves the scrollport at either edge, the animation plays backward.
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.
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>
...
<div class="animated">I am animated</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<div class="trigger1">I create a trigger</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<div class="trigger2">I create another trigger</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
<div class="trigger3">I create yet another trigger</div>
<p>
Fusce dictum ex quis ipsum consectetur placerat. Cras sed lectus ex. Quisque
purus dolor, vulputate ac mi eget, commodo varius odio. Suspendisse faucibus
ipsum vel libero finibus, in placerat nibh congue. Sed iaculis, metus et
euismod posuere, mi diam vestibulum felis, ac vulputate eros ipsum id justo.
Etiam a tincidunt purus. Maecenas semper sed enim at blandit. Aenean ut
sagittis lorem, eget gravida purus. Phasellus eleifend, lectus nec pulvinar
facilisis, dui dolor feugiat odio, iaculis tempor felis est non tortor. In
suscipit lorem efficitur molestie tempus. Integer sit amet neque et risus
iaculis sodales sed eget diam. Quisque sodales nunc sapien, vitae lacinia ex
luctus quis. Maecenas scelerisque scelerisque elit eu consequat. Etiam ac
tristique tellus, sed tincidunt velit.
</p>
body {
width: 80%;
margin: 0 auto;
font-family: "Helvetica", "Arial";
font-size: 1.3rem;
}
div {
height: 100px;
border: 5px solid black;
}
.animated {
width: 100px;
background: orange;
}
.trigger1,
.trigger2,
.trigger3 {
background: palegoldenrod;
}
The animation shorthand property value is a comma-separated list of animations, applying the same animation-name — rotate — three times. The animation-trigger value is a comma-separated list with 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();
}
@supports not (animation-trigger: --t play-forwards play-backwards) {
body::before {
content: "Your browser does not support the animation-trigger property.";
background-color: wheat;
text-align: center;
padding: 1rem 0;
z-index: 1;
position: fixed;
inset: 40% 0 auto;
}
}
Try scrolling the content up and down, and note how the animation activates and then deactivates when each trigger element scrolls into and out of view.
| Specification |
|---|
| Animation Triggers # propdef-animation-trigger |
<animation-action> typetimeline-trigger-name, timeline-trigger-source, timeline-trigger-activation-range, and timeline-trigger-active-rangetimeline-trigger shorthandtrigger-scope