files/en-us/web/css/reference/properties/animation-timing-function/index.md
The animation-timing-function CSS property sets how an animation progresses through the duration of each cycle.
It is often convenient to use the shorthand property {{cssxref("animation")}} to set all animation properties at once.
{{InteractiveExample("CSS Demo: animation-timing-function")}}
animation-timing-function: linear;
animation-timing-function: ease-in-out;
animation-timing-function: steps(5, end);
animation-timing-function: cubic-bezier(0.1, -0.6, 0.2, 0);
<section class="flex-column" id="default-example">
<div class="animating" id="example-element"></div>
<button id="play-pause">Play</button>
</section>
#example-element {
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: slide;
animation-play-state: paused;
background-color: #1766aa;
border-radius: 50%;
border: 5px solid #333333;
color: white;
height: 150px;
margin: auto;
margin-left: 0;
width: 150px;
}
#example-element.running {
animation-play-state: running;
}
#play-pause {
font-size: 2rem;
}
@keyframes slide {
from {
background-color: orange;
color: black;
margin-left: 0;
}
to {
background-color: orange;
color: black;
margin-left: 80%;
}
}
const el = document.getElementById("example-element");
const button = document.getElementById("play-pause");
button.addEventListener("click", () => {
if (el.classList.contains("running")) {
el.classList.remove("running");
button.textContent = "Play";
} else {
el.classList.add("running");
button.textContent = "Pause";
}
});
/* Keyword values */
animation-timing-function: ease;
animation-timing-function: ease-in;
animation-timing-function: ease-out;
animation-timing-function: ease-in-out;
animation-timing-function: linear;
animation-timing-function: step-start;
animation-timing-function: step-end;
/* cubic-bezier() function values */
animation-timing-function: cubic-bezier(0.42, 0, 1, 1); /* ease-in */
animation-timing-function: cubic-bezier(0, 0, 0.58, 1); /* ease-out */
animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1); /* ease-in-out */
/* linear() function values */
animation-timing-function: linear(0, 0.25, 1);
animation-timing-function: linear(0 0%, 0.25 50%, 1 100%);
animation-timing-function: linear(0, 0.25 50% 75%, 1);
animation-timing-function: linear(0, 0.25 50%, 0.25 75%, 1);
/* steps() function values */
animation-timing-function: steps(4, jump-start);
animation-timing-function: steps(10, jump-end);
animation-timing-function: steps(20, jump-none);
animation-timing-function: steps(5, jump-both);
animation-timing-function: steps(6, start);
animation-timing-function: steps(8, end);
/* Multiple animations */
animation-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1, 0.1);
/* Global values */
animation-timing-function: inherit;
animation-timing-function: initial;
animation-timing-function: revert;
animation-timing-function: revert-layer;
animation-timing-function: unset;
: The easing function that corresponds to a given animation, as determined by {{cssxref("animation-name")}}.
The non-step keyword values (ease, linear, ease-in-out, etc.) each represent cubic Bézier curves with fixed four-point values, while the cubic-bezier() function value allows non-predefined values to be specified. The steps() easing function divides the input time into a specified number of equal-length intervals. Its parameters include a number of steps and a step position.
linear
cubic-bezier(0.0, 0.0, 1.0, 1.0), animates at an even speed.ease
cubic-bezier(0.25, 0.1, 0.25, 1.0), the default value, increases in velocity towards the middle of the animation, slowing back down at the end.ease-in
cubic-bezier(0.42, 0, 1.0, 1.0), starts off slowly, with the speed of the transition of the animating property increasing until complete.ease-out
cubic-bezier(0, 0, 0.58, 1.0), starts quickly, slowing down the animation continues.ease-in-out
cubic-bezier(0.42, 0, 0.58, 1.0), with the animating properties slowly transitioning, speeding up, and then slowing down again.cubic-bezier(<number [0,1]> , <number> , <number [0,1]> , <number>)
linear(<number> <percentage>{1,2}, …)
0% and 100% respectively, and the stop points in the middle receive percentage values derived by linearly interpolating between the closest previous and next points that have a percentage value.steps(<integer>, <step-position>)
jump-start
jump-end
jump-none
jump-both
start
jump-start.end
jump-end.step-start
steps(1, jump-start)step-end
steps(1, jump-end)[!NOTE] When you specify multiple comma-separated values on an
animation-*property, they are applied to the animations in the order in which the {{cssxref("animation-name")}}s appear. For situations where the number of animations andanimation-*property values do not match, see Setting multiple animation property values.
[!NOTE]
animation-timing-functionhas the same effect when creating CSS scroll-driven animations as it does for regular time-based animations.
Easing functions may be specified on individual keyframes in a {{cssxref("@keyframes")}} rule. If no animation-timing-function is specified on a keyframe, the corresponding value of animation-timing-function from the element to which the animation is applied is used for that keyframe.
Within a keyframe, animation-timing-function is an at-rule-specific descriptor, not the property of the same name. The timing is not being animated. Rather, a keyframe's easing function is applied on a property-by-property basis from the keyframe on which it is specified until the next keyframe specifying that property, or until the end of the animation if there is no subsequent keyframe specifying that property. As a result, an animation-timing-function specified on the 100% or to keyframe will never be used.
{{cssinfo}}
{{csssyntax}}
All the examples in this section animate the width and background-color properties of several <div> elements with different animation-timing-function values. The width is being animated from 0 to 100%, and the background color is being animated from lime to magenta.
The example demonstrates the effects of various linear() easing function values.
<div class="parent">
<div class="linear">'linear' value</div>
<div class="linear-fn1">linear(0, 0.5 50%, 1)</div>
<div class="linear-fn2">linear(0, 0.25 75%, 1)</div>
<div class="linear-fn3">linear(0, 0.75 25%, 1)</div>
<div class="linear-fn4">linear(0, 0.5 25% 75%, 1)</div>
<div class="linear-fn5">linear(0, 0.25 45%, 0.75 55%, 0.5 70%, 1)</div>
<div class="linear-fn6">linear(0, 1.2 50%, 0.75 80%, 1)</div>
<div class="linear-fn7">linear(0, 0.5 75%, 1 120%)</div>
</div>
<div class="x-axis"><span>25%</span><span>50%</span><span>75%</span></div>
<button>Play animation</button>
const btn = document.querySelector("button");
const divs = document.querySelectorAll(".parent > div[class]");
btn.addEventListener("click", () => {
btn.setAttribute("disabled", "true");
for (const div of divs) {
div.classList.remove("animate");
void div.offsetWidth;
div.classList.add("animate");
}
setTimeout(() => {
btn.removeAttribute("disabled");
}, 11000);
});
.x-axis {
display: flex;
justify-content: space-evenly;
width: 80vw;
margin-left: 4px;
}
.parent {
background: linear-gradient(
to right,
white 24.8%,
grey 24.8%,
grey 25.2%,
white 25.2%,
white 49.8%,
grey 49.8%,
grey 50.2%,
white 50.2%,
white 74.8%,
grey 74.8%,
grey 75.2%,
white 75.2%
);
width: 80vw;
font-family: monospace;
font-weight: bold;
border: 2px solid grey;
}
.animate {
animation-name: changeme;
}
.parent > div[class] {
animation-fill-mode: forwards;
animation-duration: 10s;
width: 0;
margin-bottom: 4px;
padding: 5px 0;
box-sizing: border-box;
text-wrap: nowrap;
background-color: lime;
}
@keyframes changeme {
0% {
width: 0em;
}
100% {
width: 100%;
background-color: orange;
}
}
.linear {
animation-timing-function: linear;
}
.linear-fn1 {
animation-timing-function: linear(0, 0.5 50%, 1);
}
.linear-fn2 {
animation-timing-function: linear(0, 0.25 75%, 1);
}
.linear-fn3 {
animation-timing-function: linear(0, 0.75 25%, 1);
}
.linear-fn4 {
animation-timing-function: linear(0, 0.5 25% 75%, 1);
}
.linear-fn5 {
animation-timing-function: linear(0, 0.25 45%, 0.75 55%, 0.5 70%, 1);
}
.linear-fn6 {
animation-timing-function: linear(0, 1.2 50%, 0.75 80%, 1);
}
.linear-fn7 {
animation-timing-function: linear(0, 0.5 75%, 1 120%);
}
{{EmbedLiveSample("Linear function examples", 600, 300)}}
The following image shows graphs of all the linear() function values used in this example. Input progress (time) is plotted on the x-axis and output progress is plotted on the y-axis. As per the syntax, the input progress ranges from 0 to 100%, and the output ranges from 0 to 1.
Note that the output can go forward or backward.
The example demonstrates the effects of various bézier curve easing functions.
<div class="parent">
<div class="linear">linear</div>
<div class="ease">ease</div>
<div class="ease-in">ease-in</div>
<div class="ease-out">ease-out</div>
<div class="ease-in-out">ease-in-out</div>
<div class="cb">cubic-bezier(.5, -0.5, 1, 1.5)</div>
</div>
<div class="x-axis"><span>50%</span></div>
<button>Play animation</button>
const btn = document.querySelector("button");
const divs = document.querySelectorAll(".parent > div[class]");
btn.addEventListener("click", () => {
btn.setAttribute("disabled", "true");
for (const div of divs) {
div.classList.remove("animate");
void div.offsetWidth;
div.classList.add("animate");
}
setTimeout(() => {
btn.removeAttribute("disabled");
}, 11000);
});
.x-axis {
display: flex;
justify-content: space-evenly;
width: 80vw;
margin-left: 4px;
}
.parent {
background: linear-gradient(
to right,
white 49.8%,
grey 49.8%,
grey 50.2%,
white 50.2%
);
width: 80vw;
font-family: monospace;
font-weight: bold;
border: 2px solid grey;
}
.animate {
animation-name: changeme;
}
.parent > div[class] {
animation-fill-mode: forwards;
animation-duration: 10s;
width: 0;
margin-bottom: 4px;
padding: 5px 0;
box-sizing: border-box;
text-wrap: nowrap;
background-color: lime;
}
@keyframes changeme {
0% {
width: 0em;
}
100% {
width: 100%;
background-color: orange;
}
}
.linear {
animation-timing-function: linear;
}
.ease {
animation-timing-function: ease;
}
.ease-in {
animation-timing-function: ease-in;
}
.ease-out {
animation-timing-function: ease-out;
}
.ease-in-out {
animation-timing-function: ease-in-out;
}
.cb {
animation-timing-function: cubic-bezier(0.5, -0.5, 1, 1.5);
}
{{EmbedLiveSample("Cubic-Bezier_examples", 600, 250)}}
The following image shows graphs of all the cubic bézier function values used in this example. The input progress (time) ranges from 0 to 1 and the output progress ranges from 0 to 1.
This example demonstrates the effects of several step easing function values.
<div class="parent">
<div class="linear">linear</div>
<div class="start">steps(4, start)</div>
<div class="jump-start">steps(4, jump-start)</div>
<div class="end">steps(4, end)</div>
<div class="jump-end">steps(4, jump-end)</div>
<div class="jump-both">steps(4, jump-both)</div>
<div class="jump-none">steps(4, jump-none)</div>
<div class="step-start">step-start</div>
<div class="step-end">step-end</div>
</div>
<div class="x-axis"><span>25%</span><span>50%</span><span>75%</span></div>
<button>Play animation</button>
const btn = document.querySelector("button");
const divs = document.querySelectorAll(".parent > div[class]");
btn.addEventListener("click", () => {
btn.setAttribute("disabled", "true");
for (const div of divs) {
div.classList.remove("animate");
void div.offsetWidth;
div.classList.add("animate");
}
setTimeout(() => {
btn.removeAttribute("disabled");
}, 11000);
});
.x-axis {
display: flex;
justify-content: space-evenly;
width: 80vw;
margin-left: 4px;
}
.parent {
background: linear-gradient(
to right,
white 24.8%,
grey 24.8%,
grey 25.2%,
white 25.2%,
white 49.8%,
grey 49.8%,
grey 50.2%,
white 50.2%,
white 74.8%,
grey 74.8%,
grey 75.2%,
white 75.2%
);
width: 80vw;
font-family: monospace;
font-weight: bold;
border: 2px solid grey;
}
.animate {
animation-name: changeme;
}
.parent > div[class] {
animation-fill-mode: forwards;
animation-duration: 10s;
width: 0;
margin-bottom: 4px;
padding: 5px 0;
box-sizing: border-box;
text-wrap: nowrap;
background-color: lime;
}
@keyframes changeme {
0% {
width: 0em;
}
100% {
width: 100%;
background-color: orange;
}
}
.linear {
animation-timing-function: linear;
}
.start {
animation-timing-function: steps(4, start);
}
.jump-start {
animation-timing-function: steps(4, jump-start);
}
.end {
animation-timing-function: steps(4, end);
}
.jump-end {
animation-timing-function: steps(4, jump-end);
}
.jump-both {
animation-timing-function: steps(4, jump-both);
}
.jump-none {
animation-timing-function: steps(4, jump-none);
}
.step-start {
animation-timing-function: step-start;
}
.step-end {
animation-timing-function: step-end;
}
{{EmbedLiveSample("Step_examples", 600, 350)}}
The following image shows graphs of all the step() function values used in this example. The input progress (time) and output progress range from 0 to 1.
{{Specifications}}
{{Compat}}