animation-timeline
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The animation-timeline CSS property specifies the timeline used to control the progress of a CSS animation.
Syntax
/* Keyword */
animation-timeline: none;
animation-timeline: auto;
/* Named timeline */
animation-timeline: --timeline_name;
/* Anonymous scroll progress timeline */
animation-timeline: scroll();
animation-timeline: scroll(x root);
/* Anonymous view progress timeline */
animation-timeline: view();
animation-timeline: view(inline);
animation-timeline: view(x 200px auto);
/* Multiple values */
animation-timeline: --progress-bar-timeline, --carousel-timeline;
animation-timeline: auto, view(20% 80%), none, scroll(inline nearest);
/* Global values */
animation-timeline: inherit;
animation-timeline: initial;
animation-timeline: revert;
animation-timeline: revert-layer;
animation-timeline: unset;
Values
The animation-timeline property is specified as one or more comma-separated values, each of which can be one of the following:
none-
The animation is not associated with a timeline, and no animation occurs.
auto-
The animation's timeline is the document's default
DocumentTimeline. This is the default value. scroll()-
Defines the root element, nearest scroller, or self as an anonymous scroll progress timeline, and optionally the scroll direction of the scroller.
view()-
Defines the nearest ancestor scroll container as an anonymous view progress timeline, optionally overriding the default
baselineaxis direction and theautostart and ending insets. <dashed-ident>-
The name of a scroll-driven or view-progress timeline, as defined by the scroll container's
scroll-timeline-nameorview-timeline-nameproperty (or thescroll-timelineorview-timelineshorthand property).
Description
The default timeline for a CSS keyframe animation is the time-based DocumentTimeline. The animation-timeline property can be used to set a named or anonymous scroll progress or view progress timeline. Alternatively, it can be used to explicitly set the default time-based document timeline to control the progress of an element's animation or to have no timeline at all, in which case the element does not animate.
The following types of timelines can be set via animation-timeline:
DocumentTimeline-
The default document timeline, which is progressed through by the passing of time since the document was first loaded in the browser. This is the timeline traditionally associated with CSS animations and is selected with a value of
auto, or by not specifying ananimation-timelinevalue at all, as this is the default value. - Scroll progress timeline
-
The animation is progressed through by scrolling a scrollable element, or scroller, horizontally or vertically. The element that provides the scroll progress timeline can be specified in two ways:
- Named scroll progress timeline
-
The scroller is explicitly named by setting the
scroll-timeline-nameproperty (or thescroll-timelineshorthand property) to a<dashed-ident>; that<dashed-ident>name is then set as the value of theanimation-timelineproperty. - Anonymous scroll progress timeline
-
The
animation-timelineproperty of the element to animate is set to thescroll()function. The function's two optional parameters define the scroller providing the scroll progress timeline and the scroll axis to be used.
- View progress timeline
-
A keyframe animation is progressed through based on the change in visibility of an element inside a scroller; this element is known as the subject. By default, the timeline is at
0%when the element first becomes visible at one edge of the scroller, and is at100%when its end edge exits the scroller's opposite edge. A view progress timeline can be specified in two ways:- Named view progress timeline
-
The subject is explicitly named by setting the
view-timeline-nameproperty (or theview-timelineshorthand property) to a<dashed-ident>. When you set theanimation-timelineproperty of the element to animate to that<dashed-ident>, the subject's visibility controls the progression of the element's animation. Note that the element to animate does not have to be the same as the subject. - Anonymous view progress timeline
-
The
animation-timelineproperty of the element to animate is set to aview()function, causing it to be animated based on its visibility within the scrollport of its nearest parent scroller.
- No timeline
-
All animation timelines can be removed by selecting a value of
none. Whenanimation-timeline: noneis set, no animation will occur as there is no timeline to follow.
The animation-timeline property is included in the animation shorthand as a reset-only value. This means that including animation resets a previously-declared animation-timeline value to auto. As this component of the shorthand is reset-only, a specific value cannot be set via animation. When creating CSS scroll-driven animations, you need to declare animation-timeline after declaring any animation shorthand for it to take effect.
If you specify multiple comma-separated values, each animation-timeline value is applied to a single animation in the order in which the animation-name values appear. If the number of values in the animation-timeline declaration is greater than the number of animation-name values, the excess timeline values are ignored. If there are fewer animation-timeline values than animation-name values, the animation-timeline values are repeated, in order, until every animation-name has an associated timeline.
If two or more timelines share the same <dashed-ident> name and the same specificity, the one last declared within the cascade will be used. If no timeline is found that matches a name included within the animation-timeline, the animation-name associated with that value is not associated with a timeline.
Formal definition
| Initial value | auto |
|---|---|
| Applies to | all elements |
| Inherited | no |
| Computed value | a list, each item either a case-sensitive CSS identifier or the keywords none, auto |
| Animation type | Not animatable |
Formal syntax
animation-timeline =
<single-animation-timeline>#
<single-animation-timeline> =
auto |
none |
<dashed-ident> |
<scroll()> |
<view()>
<scroll()> =
scroll( [ <scroller> || <axis> ]? )
<view()> =
view( [ <axis> || <'view-timeline-inset'> ]? )
<scroller> =
root |
nearest |
self
<axis> =
block |
inline |
x |
y
<view-timeline-inset> =
[ [ auto | <length-percentage> ]{1,2} ]#
<length-percentage> =
<length> |
<percentage>
Examples
Basic usage
This example demonstrates basic usage of the animation-timeline property, along with the none, auto, and default (auto) values.
HTML
We have an <article> with three <section> children. Each <section> has a unique id and a <div> child.
<article>
<section id="none">
<div></div>
</section>
<section id="auto">
<div></div>
</section>
<section id="default">
<div></div>
</section>
</article>
CSS
We use flexible box layout to set the three sections side-by-side. We use generated content to display the id. We style all elements the same, applying the rotate @keyframes animation that rotates the element by 1 full turn. Using the animation shorthand, we declare infinite, 2-second, linearly progressing iterations of the rotate animation, alternating the direction of each animation.
article {
display: flex;
gap: 10px;
text-align: center;
}
section {
background-color: beige;
padding: 20px;
}
section::after {
content: attr(id);
display: block;
}
div {
height: 100px;
width: 100px;
background-color: magenta;
animation: rotate 2s infinite alternate linear;
}
@keyframes rotate {
to {
rotate: 1turn;
}
}
The only difference is the animation-timeline declaration (or lack thereof in the case of default) for each <div>.
#none div {
animation-timeline: none;
}
#auto div {
animation-timeline: auto;
}
Because the animation-timeline property is included in the animation shorthand as a reset-only value, the animation-timeline must come after the animation shorthand, or be applied with greater specificity than the animation shorthand, to be applied.
Results
Note that declaring a value of auto has the same effect as allowing the animation-timeline to default to that value, and that none removes all timelines from the element, so no animation in the none case.
Setting a named scroll progress timeline
In this example, the animation timeline is set to a horizontal scroll progress timeline.
HTML
Our container includes three stretcher elements which will be wide enough to ensure our container is a scroll container. The middle one contains a shape that we will animate.
<div id="container">
<div class="stretcher"></div>
<div class="stretcher">
<div id="shape"></div>
</div>
<div class="stretcher"></div>
</div>
CSS
We define the container as a flex container, setting a width on the container that is half the width of it's combined flex children. Adding an overflow-x value of scroll sets it to have a horizontal scrollbar.
Our scroll progress timeline, defined using the scroll-timeline-name and scroll-timeline-axis properties, is named --square-timeline. This timeline is applied to our #square element using animation-timeline: --square-timeline.
#container {
display: flex;
width: 300px;
border: 1px solid;
overflow-x: scroll;
scroll-timeline-axis: inline;
scroll-timeline-name: --square-timeline;
}
.stretcher {
flex: 0 0 200px;
}
The CSS below defines a square that rotates in alternate directions according to the timeline provided by the animation-timeline property, which is set to the --square-timeline timeline named above. The animation is set two occur twice, in alternating directions, as it passes through the viewport. We added notched corners to make the animation effect more apparent.
#shape {
background-color: deeppink;
width: 100px;
height: 100px;
border-radius: 25px;
corner-shape: notch;
animation: rotateAnimation 1ms linear 2 alternate;
animation-timeline: --square-timeline;
}
@keyframes rotateAnimation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Result
Scroll to see the element being animated.
Setting an anonymous scroll progress timeline
This example expands on the previous one, applying an anonymous scroll progress timeline using the scroll() function.
CSS
We include all the CSS from the previous example, only setting the animation-timeline property to override the previous example's value. The timeline is provided by the scroll(inline nearest) value, which selects the scrollbar in the inline direction of the nearest ancestor element that has scrollbars. This is the vertical scrollbar of the #container element, as the .stretcher elements don't have overflowing content and therefore aren't scroll containers.
#shape {
animation-timeline: scroll(inline nearest);
}
Result
Scroll to see the square element being animated.
Setting a named view progress timeline
In this example, we demonstrate how to create and apply a named view progress timeline. Two elements will be animated, with different elements serving as the scroller.
HTML
Our HTML includes a lot of text in a container within a scroller, which we've hidden for brevity. In the middle of the wall of text, we include two <div> elements that we will animate based on the visibility of the element itself in the first case and based on the visibility of its parent in the second case:
<div class="animatedElement self">SELF</div>
<div class="animatedElement parent">PARENT</div>
CSS
We create a keyframe animation that changes the opacity and scale of the element, and apply it to both animated elements:
@keyframes animationEffect {
0% {
opacity: 0;
scale: 0;
}
100% {
opacity: 1;
scale: 1;
}
}
.animatedElement {
animation: animationEffect 1ms linear;
}
The self element is explicitly named as the scroller for itself by setting the view-timeline-name property to a <dashed-ident> and also setting that <dashed-ident> name as the value of the animation-timeline property. In the parent case, we set the container as the scroller for the animated element:
.self {
view-timeline-name: --selfScrollerElement;
animation-timeline: --selfScrollerElement;
}
.container {
view-timeline-name: --parentScrollerElement;
}
.parent {
animation-timeline: --parentScrollerElement;
}
Additional CSS declarations were hidden for brevity.
Result
Scroll the container to see both elements animate.
Note how the visibility of the self element controls its own animation. In this case, the element is at the 0% keyframe when the top edge enters the viewport, or visible part of the scrollport, and only reaches the 100% keyframe when the bottom edge exits the viewport.
The parent element only becomes visible when that parent is visible, meaning that when it comes into view, it is already about 25% of the way through the animation. It is only about 75% through its animation when it exits the top of the viewport.
Specifications
| Specification |
|---|
| CSS Animations Level 2 # animation-timeline |
Browser compatibility
See also
animation,animation-composition,animation-delay,animation-direction,animation-duration,animation-fill-mode,animation-iteration-count,animation-name,animation-play-state,animation-timing-functionscroll-timeline-name,scroll-timeline-axis,scroll-timelineview-timeline-name,view-timeline-axis,view-timeline,view-timeline-insetAnimationTimeline- Guide: Using CSS animations
- CSS animations module
- CSS scroll-driven animations module