CSS & Web Design 7 min read • Published 2026-03-24

The Physics of UI Motion: Crafting Custom Cubic-Bezier Curves & Easing Functions

Master animation timing functions: why linear feels robotic, the difference between ease-out and ease-in, and how to create natural springy bouncy physics with cubic-bezier.

Why Default Easing Functions Fall Short

Movement in the physical world is governed by mass, momentum, and friction. Objects never start or stop instantaneously. Default browser transitions like linear feel artificial and robotic because speed remains completely uniform from start to end.

Understanding Cubic-Bezier Coordinate Physics

A CSS cubic-bezier curve is defined by four coordinates: cubic-bezier(x1, y1, x2, y2) representing two control points on a unit graph:

  • P0 (0, 0): The start of the animation (time = 0, progression = 0).
  • P1 (x1, y1): The first control handle shaping initial acceleration.
  • P2 (x2, y2): The second control handle shaping final deceleration.
  • P3 (1, 1): The completion point (time = 1, progression = 1).

Because time cannot flow backward, the X coordinates (x1 and x2) are strictly constrained between 0.0 and 1.0. However, the Y coordinates (progression) can exceed 1.0 or dip below 0.0!

Creating Realistic Spring and Bounce Effects

By extending y1 or y2 above 1.0, the animating element physically overshoots its final destination before springing backward into place:

/* Natural Spring Ease-Out Bounce */
.modal-popup {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

This timing curve gives dropdowns, modals, and buttons an organic tactile responsiveness reminiscent of native iOS and macOS interface interactions.

Experiment with bezier control handles and test live animations using WebUtilities's CSS Cubic-Bezier Curve Visualizer.

Try the Related Tools: