Easing is the function that maps time progress to animation progress, controlling the perceived acceleration and deceleration of motion. CSS provides several built-in keywords. ease is the default and is equivalent to cubic-bezier(0.25, 0.1, 0.25, 1.0); it produces a gentle slow-fast-slow curve. linear is constant speed from start to end, equivalent to cubic-bezier(0, 0, 1, 1). ease-in starts slow and accelerates toward the end (cubic-bezier(0.42, 0, 1, 1)). ease-out starts fast and decelerates toward the end (cubic-bezier(0, 0, 0.58, 1)) and is good for elements coming to rest. ease-in-out accelerates in the middle and is slow at the start and end (cubic-bezier(0.42, 0, 0.58, 1)).
For custom curves, cubic-bezier() takes four numbers P1x, P1y, P2x, P2y. The x values must lie in the range 0–1 and represent time progress, while the y values represent value progress and may go outside 0–1 to create overshoot effects. Overshoot easing, where the animation goes past the target value before settling to create a spring-like feel, is achieved with a cubic-bezier whose y2 is greater than 1. The curve itself is a Bézier curve whose shape determines how the animation feels.
The steps() timing function divides an animation into a fixed number of discrete jumps instead of smoothly interpolating, producing a staircase-like progress. steps(n, jump-end) means the animation jumps at the END of each step: the element shows the start value until each step completes, then snaps to the next value. steps(n, jump-start) means the animation jumps at the START of each step, with the first value change shown immediately and n-1 more jumps following. The key contrast is that normal easing functions produce continuous, smooth interpolation, while steps() produces discrete frames.
For animations, animation-timing-function applies to the easing between each pair of adjacent keyframes, not across the whole animation, so different keyframe pairs can use different easings. Each keyframe selector in a @keyframes block can include its own animation-timing-function to control how it moves to the next. This allows, for example, a fast entry into a midpoint and a slow drift back out.