Animation and Transition Timing
CSS transitions and animations don't just happen over a certain duration; they also follow a speed curve, which defines how quickly the animation starts, accelerates, and decelerates throughout its run time. This speed control is managed by the timing function.
The properties used are:
transition-timing-function(for simple transitions)animation-timing-function(for keyframe animations)
1. Standard Timing Keywordsβ
The simplest way to control animation speed is by using one of the five standard keywords. Each keyword is a predefined implementation of the more complex cubic-bezier() function.
| Keyword | Description | Curve Behavior |
|---|---|---|
ease (Default) | Starts slowly, speeds up quickly in the middle, and ends slowly. | Recommended for most smooth UI interactions. |
linear | Maintains a constant speed from start to finish. | Useful for continuous, cyclical animations (like a spinner). |
ease-in | Starts slowly and steadily accelerates until the end. | Gives the feeling of an element accelerating away from the user. |
ease-out | Starts quickly and steadily decelerates until the end. | Gives the feeling of an element slowing to a stop. |
ease-in-out | Starts and ends slowly, with a fast middle section. | Symmetrical, smooth motion in both directions. |
Example Usageβ
.box-in {
/* Starts slow, ends fast */
transition-timing-function: ease-in;
}
.box-linear {
/* Consistent speed */
animation-timing-function: linear;
}
2. Customizing with cubic-bezier()β
The cubic-bezier(n, n, n, n) function gives you complete control over the speed curve. It accepts four numerical parameters between 0 and 1, which define the coordinates of two control points ( and ) on a BΓ©zier curve.
The curve charts the progress of the animation (Y-axis, from 0 to 1) against the time elapsed (X-axis, from 0 to 1).
- : Fixed at the start of the animation (0, 0).
- : Fixed at the end of the animation (1, 1).
- : Control point one, defined by .
- : Control point two, defined by .
Syntaxβ
/* Custom Bezier curve for an aggressive, fast start and slow finish */
transition-timing-function: cubic-bezier(0.8, 0.1, 0.2, 0.9);
You can use online tools (like cubic-bezier visualizers) to experiment with these four values and create highly customized motion.
3. Discrete Movement with steps()β
For animations that need to jump between states rather than transition smoothly, you use the steps() function. This is ideal for things like sprite-based animation, blinking effects, or simulating a clock with discrete ticks.
Syntaxβ
The function requires two parameters:
steps(number_of_steps, step_position);
number_of_steps: The total number of equally spaced intervals the animation will pause during its duration.step_position: Defines where the jump occurs relative to the interval.end(Default): The change happens at the end of each time interval (holds for the full interval, then jumps).start: The change happens at the beginning of each time interval (jumps immediately, then holds).
Example: Stepped Clock Handβ
If an animation runs for 60 seconds and you want it to jump 60 times (once per second):
animation: tick 60s steps(60, end);
The animation will run in 60 discrete jumps over 60 seconds.
Interactive Timing Function Demoβ
The three boxes below execute the same translateX(200px) transition over the same duration, but each uses a different timing function, demonstrating how the speed curve dramatically changes the feel of the movement.
In this demo, hovering over the container triggers the translation of each box. You can see how the different timing functions affect the speed and feel of the movement.