Cubic bezier curves: what the four numbers actually control

How cubic bezier curves shape motion, and where the standard easing presets fall short. Written for designers who want easing that says something.

Build your curve in Cubic Bezier Architect Set up your colour tokens in CSS Variable Architect

Open any CSS transition property in DevTools and you'll usually find ease sitting there by default, doing a job it wasn't built for. A button that should snap into place drifts. A modal that should feel weighty floats in like it's underwater. The problem isn't that ease is broken. It's that almost no interface motion actually wants the curve it describes, and most designers never look past it to see what else is available.

What a cubic bezier curve actually controls

A cubic bezier timing function describes how a value changes over the duration of an animation. Duration is a separate number. The curve answers a different question: at the halfway point in time, is the animation halfway through its movement, a tenth of the way through, or nearly finished? That relationship between elapsed time and elapsed motion is the entire subject.

In CSS the function takes four numbers: cubic-bezier(x1, y1, x2, y2). Picture a square with time running left to right along the bottom and progress running bottom to top on the left side. The curve always starts at the bottom-left corner and ends at the top-right corner, because every animation starts at 0% and finishes at 100%. The two coordinate pairs you supply are control points that pull the line between those corners into a shape. Move the first point up and the animation accelerates hard at the start. Move the second point down and it drags its feet before it finishes.

Why the y-values can go past 0 and 1

The x-values in a bezier function have to stay between 0 and 1, because time only moves forward. The y-values don't have that restriction. Push a y-value above 1 and the animated property overshoots its target before settling back, which is how you get a button that pops slightly past its resting size before easing home. Push a y-value below 0 and the element dips backward before it moves forward, the visual equivalent of a golfer's backswing. Both are legitimate, and both are invisible if you only ever reach for the built-in keywords.

Why the shape matters more than the numbers

Two curves with wildly different coordinates can look almost identical once you see them play out, and two curves with similar-looking coordinates can feel completely different in motion. This is why staring at four decimal numbers rarely tells you anything useful. What tells you something is watching the curve move, which is the entire reason to reach for a visual editor. Our cubic bezier architect plots the curve as you drag its handles and plays the motion back against a moving element, so you're judging the feel. The preview gives a close approximation of how the timing function will behave, but actual rendering can vary a little between browsers and between GPU-accelerated and non-accelerated properties, so it's worth checking the motion in the real interface before you commit to it.

The reason the shape carries the meaning is that human perception reads acceleration and deceleration as physical qualities: weight, urgency, resistance. A curve that eases out slowly reads as something settling under its own mass. A curve that snaps in and holds reads as something being pushed by an outside force. Designers who animate by feel are really choosing a small story about what kind of object is moving, whether they think of it that way or not.

Common mistakes with easing curves

  • Using ease-in-out for everything. It's a safe, symmetrical curve, which is exactly why it reads as generic. Entrances and exits are rarely symmetrical events, and treating them as if they were flattens the distinction between something appearing and something being dismissed.
  • Applying the same curve to enter and exit. An element entering the screen usually benefits from a fast start and a gentle landing, so the user's eye can track it settling into place. An element leaving benefits from the opposite: a slower start that gives the eye a moment to register the change, followed by a quick exit. Reusing one curve for both directions is a common shortcut that quietly undercuts both.
  • Choosing a curve before choosing a duration. A pronounced overshoot that feels playful at 400 milliseconds can feel sluggish and indecisive stretched to 800. Curve and duration are read together.
  • Copying a curve from somewhere else without checking what it's attached to. A bounce that suits a floating action button can look absurd on a full-page transition. Scale and context change what a given curve communicates.

Building curves that match the motion you want

Start from the kind of movement you're trying to describe. A short list of starting points, each aimed at a different feeling:

  • Something appearing on screen: a fast start with control points weighted early, then a soft deceleration into place, so the object feels like it arrives with purpose but doesn't crash.
  • Something being dismissed: a brief pause before acceleration, so the eye has time to register that a change is happening before the element commits to leaving.
  • A playful confirmation, such as a like button or a toggle: a slight overshoot past the resting state, using a y-value above 1, gives the impression of a small spring.
  • A loading or progress indicator: something closer to linear, because irregular acceleration on a repeating animation tends to read as stuttering.

Once you've settled on a curve that reads correctly for a given interaction, it's worth keeping it consistent across every instance of that interaction type. Storing the value as a custom property, the kind of token covered in the CSS Variable Architect, means every modal, drawer or toast in a design system shares the same sense of weight.

Checking a curve against real content

A curve that looks right on a small demo box can behave differently against a full-width card or a long list, because larger elements make more of the screen change at once and small imperfections in the timing become easier to see. Test against the actual component at its actual size before treating a curve as finished.

If a term like easing function, keyframe or interaction design comes up and the meaning isn't settled, the Design Glossary covers how practitioners actually use it, cross-referenced against related terms.

See the curve before you commit to it

Dragging the two handles and watching the timing shift tells you more than reading the numbers ever does, and it can still hand you a curve that looks right and moves wrong.