Why Animation Speed Matters

Animation quality is about more than just visual design — the rate at which an element moves between states shapes how the motion is perceived. Easing functions, also called timing functions, control that rate of change. Pre-defined keywords like ease-out are convenient, but relying on the same duration and easing values across many page elements can make a UI feel flat. Natural motion, which is rarely constant-speed, tends to resonate better with users and creates a more polished experience.

The difference becomes apparent when comparing a site that uses varied timing functions to one that defaults to a single easing. A project with only ease-out applied everywhere still functions correctly, but the animations lose their distinct character. Custom cubic-bezier functions, mixed with pre-defined linear and ease-in values, allow each motion to feel intentional and aligned with the content it accompanies.

Basics Of Animation Timing

CSS animations and transitions both depend on keyframes that define an element's visual state at specific points. Transitions operate between two keyframes — the starting and ending values — while CSS animations offer finer control via the @keyframes rule. The animation duration is the time it takes to move from the first keyframe to the last.

Between keyframes, the animation can progress in many ways: at a constant rate, quickly at first and then decelerating, or slowly before speeding up. The easing function defines that trajectory, and it is visually represented by the shape of the line or curve connecting the two keyframe values. If the animation includes multiple keyframes, the easing function is applied independently to each segment between consecutive pairs.

Classification Of Easing Functions

CSS supports three primary categories of easing functions:

  • Linear functions, defined with the linear keyword.
  • Cubic Bézier functions, which include the pre-defined ease, ease-in, ease-out, and ease-in-out values.
  • Staircase functions, defined with the steps keyword.

Linear Functions

With a linear timing function, the animation moves at a constant speed across the defined duration. While this is straightforward to apply via the linear keyword, it is rarely the most visually appealing choice. Overusing it can produce an artificial, mechanical feel that lacks the natural acceleration and deceleration users expect from high-quality interactive motion.

Cubic Bézier Curves

Bézier curves are widely used in vector graphics and animation for creating smooth paths. CSS employs a Cubic Bézier variant defined by four control points, though the cubic-bezier() function only requires two parameters.

The first point (P0) and last point (P3) are fixed: P0 is the initial animation state, and P3 is the final state. The two remaining points (P1 and P2) let you shape the curve to control where the animation accelerates or decelerates. The x-coordinates (x1, x2) represent the time ratio and are constrained to values between 0 and 1, since the animation cannot start early or extend beyond its specified duration. The y-coordinates (y1, y2) control the animation's output value; these are not strictly limited to the 0–1 range, and values outside that range can produce bouncing or overshoot effects.

The pre-defined ease, ease-in, ease-out, and ease-in-out values are all cubic Bézier shortcuts. Crafting custom functions gives you more direct control over an animation's feel and can create a much more impactful result than relying on those presets alone. Because adjusting the curve parameters by trial and error is impractical, you will typically rely on visual tools to find the appropriate values.

Staircase Functions

Staircase functions create a non-continuous, stepped animation that jumps between a specific number of frames. This produces a "ticking" effect rather than a smooth glide. For an element moving between two positions with a limit of five steps, the animation jumps directly to distinct intermediate values rather than passing through every pixel along the way.

The steps() function in CSS accepts a second argument, the jump term, which controls which keyframes are included in the visible animation:

  • jump-start: The animation jumps at the starting point, so the initial value is never visible. The visible keyframes begin after the first jump.
  • jump-end: The final jump occurs as the animation ends and is not displayed. The last visible keyframe precedes the endpoint.
  • jump-both: Both the first and last jumps happen outside the visible range. The jumps are distributed within the timeline.
  • jump-none: The first and last keyframe values are both visible, with all jumps occurring between them.

Dedicated Tools For Refining Motion

Creating the right easing curve typically requires experimentation and visual feedback rather than manual coordinate guessing. A few categories of tools make this practical.

Browser Developer Tools

Modern browser developer tools include easing editors that support Cubic Bézier functions with an instant preview. This lets you adjust the curve and see the effect immediately without reloading the page. Chrome, Safari, and Firefox also provide a dedicated Animations panel that shows details like duration, timeline, keyframes, delay, and other relevant properties, giving you a fuller picture of each animation's configuration.

Online Easing Resources

Several web-based tools offer easing presets and calculators. The Easing Functions Cheat Sheet and the CSS Easing Animation Tool both provide a library of preset curves that you can use as a starting point and fine-tune to fit your specific timeline. These resources are helpful for discovering varied functions beyond the standard presets and for saving time when refining your own custom values.

Easing and Accessibility: A Necessary Pairing

Easing choices don't exist in a vacuum. For a meaningful number of users, animation itself is a problem, not a delight. The prefers-reduced-motion media query is the standard tool for addressing this, allowing you to serve a calmer experience to those who request it. The query’s support is broad, and using it is straightforward: wrap your standard animation in a media block and provide an alternative for users who prefer less motion.

Consider a classic analog clock. In its default state, the seconds hand ticks smoothly each second, which can be visually demanding for some. A simple fix is to swap the continuous animation for a stepped one using the steps() timing function. The result is an animation where the hand jumps every five seconds, a much less distracting experience for users who have the reduced-motion preference set in their operating system.

.animated-element {
  animation: /* Regular animation */;
}

@media (prefers-reduced-motion) {
  .animated-element {
    /* Accessible animation with reduced motion */
  }
}

The adjustment can be as minimal as changing a single property. By applying a staircase function conditionally, you retain the essence of the visual metaphor — a ticking clock — without the constant, potentially uncomfortable motion.

@media (prefers-reduced-motion) {
  .arm.second {
    animation-timing-function: steps(12);
  }
}

Timing Functions in Review

Easing functions, also known as timing functions, dictate the rate of change during an animation. By tuning that rate, you are ultimately tuning how natural and polished a motion feels. The pre-defined keywords such as linear, ease, or ease-out are the quickest path to a decent effect. When you need something more distinctive, the cubic-bezier() function offers full control over the curve, enabling a custom feel that can elevate an interface. Staircase functions, which implement discrete jumps rather than smooth interpolation, round out the toolkit and are the go-to for "ticking" effects.

None of this is worth anything if it is not accessible. Always pair your animation with a prefers-reduced-motion fallback. Doing so is a small extra step with a large payoff in usability, and it ensures that your carefully crafted motion does not become a barrier.

There is no shortage of tooling to help you experiment. Both Firefox Developer Tools and Chrome DevTools include animation inspectors, and a variety of online generators simplify the creation of bespoke cubic-bezier() curves. These resources make the act of building a personal library of easing functions a practical exercise rather than a chore. If you have not played with easing outside the defaults, now is a good time to start.

References

Further Reading

Smashing Editorial