CSS animation-timing-function Property
The animation-timing-function is a CSS property which sets the speed of an animation through the duration of each cycle.
The animation-timing-function property defines how an animation progresses over the duration of each cycle — not across the whole animation. It sets the animation's speed curve: the rate at which the animated element moves from one keyframe to the next.
This page covers what the property does, every value it accepts (including cubic-bezier() and steps()), how it interacts with @keyframes and the animation shorthand, and the gotchas that trip people up.
Why the timing function matters
An animation's duration tells you how long a cycle takes; the timing function tells you how that time is distributed. With the same 5-second duration, linear moves at a constant pace, while ease glides in slowly, speeds up in the middle, and slows to a stop. Choosing the right curve is the difference between a motion that feels mechanical and one that feels natural.
Timing functions define the interpolation between keyframe stops. That means you can set a different timing function on individual keyframes inside @keyframes — the function applies from that keyframe to the next one, not to the whole animation. If a keyframe doesn't specify one, the element's animation-timing-function value is used for that interval.
The animation-timing-function property is one of the CSS3 properties.
It can take the following values:
ease- (default) Starts slowly, then becomes faster, and ends slowly.ease-in- Starts slowly, but accelerates at the end.ease-out- Starts quickly, but slows down at the end.ease-in-out- Starts slowly and ends slowly.step-start- Equivalent tosteps(1, start).step-end- Equivalent tosteps(1, end).linear- The animation has the same speed throughout the animation, often best used for color or opacity changes.steps(int, start|end)- Specifies a stepping function with two parameters. The first parameter defines the number of intervals in the function. It must be greater than 0. The second parameter is either the value "start" or "end", and specifies the point at which the change of values occurs within the interval. If the second parameter is omitted, "end" is used.cubic-bezier(n,n,n,n)- Specifies custom values for the cubic-bezier function. The first two parameters define the X coordinates and must be between 0 and 1. The last two parameters define the Y coordinates and can be any number.
When multiple comma-separated values are specified, they map to the corresponding animations defined in animation-name in order. If there are fewer timing functions than animations, the list is repeated to match the count.
Understanding cubic-bezier()
All of the named keywords are shortcuts for a cubic-bezier() curve. The function takes four numbers — cubic-bezier(x1, y1, x2, y2) — that are the two control points of a Bézier curve running from (0,0) to (1,1). The X axis is time (which must stay between 0 and 1) and the Y axis is animation progress (which can overshoot below 0 or above 1 to create "bounce" or "anticipation" effects).
The named keywords are equivalent to:
linear→cubic-bezier(0, 0, 1, 1)ease→cubic-bezier(0.25, 0.1, 0.25, 1)ease-in→cubic-bezier(0.42, 0, 1, 1)ease-out→cubic-bezier(0, 0, 0.58, 1)ease-in-out→cubic-bezier(0.42, 0, 0.58, 1)
steps() and stepped animations
While cubic-bezier() produces smooth motion, steps() jumps between discrete states — useful for sprite-sheet animations or a typing-cursor blink. steps(4, end) divides the animation into 4 equal jumps; start makes the first jump happen immediately, while end (the default) delays it to the end of each interval.
Gotchas
- It is not inherited and not animatable. You can't transition the timing function itself.
- Order matters in the shorthand. Inside the
animationshorthand, the timing function and theanimation-delayare both<time>-or-keyword values; the first<time>is read as the duration and the second as the delay, so put your timing function before the delay value. - Per-keyframe functions win. A timing function declared on a keyframe inside
@keyframesoverrides the property value for that segment.
| Initial Value | ease |
|---|---|
| Applies to | All elements. It also applies to ::before and ::after pseudo-elements. |
| Inherited | No |
| Animatable | No |
| Version | CSS3 |
| DOM Syntax | object.style.animationTimingFunction = "linear"; |
Syntax
Syntax of CSS animation-timing-function Property
animation-timing-function: linear | ease | ease-in | ease-out | ease-in-out | step-start | step-end | steps(int,start|end) | cubic-bezier(n,n,n,n) | initial | inherit;Example of the animation-timing-function property with the "ease" value:
Example of CSS animation-timing-function Property with ease value
<!DOCTYPE html>
<html>
<head>
<title>The title of the document</title>
<style>
div {
width: 100px;
height: 100px;
border-radius: 50%;
background: #1c87c9;
position: relative;
animation: element 5s infinite;
animation-timing-function: ease;
}
@keyframes element {
from {
left: 0px;
}
to {
left: 200px;
}
}
</style>
</head>
<body>
<h2>Animation-timing-function example</h2>
<div></div>
</body>
</html>Example of the animation-timing-function property with the "ease-in" value:
Example of CSS animation-timing-function Property with ease-in value
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: #8ebf42;
position: relative;
animation: element 7s infinite;
animation-timing-function: ease-in;
}
@keyframes element {
from {
left: 0px;
}
to {
left: 200px;
}
}
</style>
</head>
<body>
<h1>The animation-timing-function Property</h1>
<div></div>
</body>
</html>Example of the animation-timing-function property with different timing functions:
Example of CSS animation-timing-function Property with linear,ease,ease-in, ease-out and ease-in-out values
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
border-radius: 50%;
background: #1c87c9;
color: #eee;
font-weight: bold;
position: relative;
text-align: center;
padding: 8px;
animation: mymove 5s infinite;
}
#div1 {
animation-timing-function: linear;
}
#div2 {
animation-timing-function: ease;
}
#div3 {
animation-timing-function: ease-in;
}
#div4 {
animation-timing-function: ease-out;
}
#div5 {
animation-timing-function: ease-in-out;
}
@keyframes mymove {
from {
left: 0px;
}
to {
left: 300px;
}
}
</style>
</head>
<body>
<h2>Animation-timing-function example</h2>
<div id="div1">linear</div>
<div id="div2">ease</div>
<div id="div3">ease-in</div>
<div id="div4">ease-out</div>
<div id="div5">ease-in-out</div>
</body>
</html>Values
| Value | Description | Play it |
|---|---|---|
| ease | The animation starts slowly, then becomes faster and ends slowly. This is the default value. | Play it » |
| linear | Proceeds at a constant speed throughout the animation. | Play it » |
| ease-in | The animation starts slowly, but becomes faster at the end. | Play it » |
| ease-out | The animation starts quickly, but slows down at the end. | Play it » |
| ease-in-out | The animation starts slowly and ends slowly. | Play it » |
| step-start | Equivalent to steps(1, start). | |
| step-end | Equivalent to steps(1, end). | |
| steps(int,start|end) | Specifies a stepping function with two parameters. The first parameter specifies the number of intervals in the function. It must be greater than 0. The second parameter is either the value "start" or "end", and specifies the point at which the change of values occur within the interval. If the second parameter is not applied, the value "end" is given. | |
| cubic-bezier (n,n,n,n) | Defines the values by cubic-bezier function. The first two parameters are X coordinates (0 to 1), and the last two are Y coordinates (can be any number). | |
| initial | It makes the property use its default value. | |
| inherit | It inherits the property from its parent element. |
Related properties
- animation — the shorthand that sets the timing function along with name, duration, delay, and more.
- @keyframes — where you define the animation stops the timing function interpolates between.
- animation-duration — sets how long one cycle lasts; the timing function distributes motion across it.
- animation-name — binds the element to a
@keyframesrule. - transition-timing-function — the same speed-curve concept applied to transitions instead of keyframe animations.