CSS Easing and cubic-bezier Explained: ease vs linear and the 4 Values
What makes an animation feel "pleasant" rather than "clunky" is the easing: how speed is distributed over time. This article explains the difference between common keywords like ease, linear, and ease-in-out, what the four values in cubic-bezier(x1,y1,x2,y2) mean as control points, how the curve relates to motion, how to specify it in transition and animation, and how to create natural movement.
The color change when you hover over a button, or a menu that slides smoothly open. Even with the same "moves in 0.3 seconds," the impression changes dramatically just by how it starts and stops. The thing that decides this pacing (how speed is applied) is easing. This article explains CSS easing and cubic-bezier, which lets you design it freely, step by step so even beginners can understand how it works.
What Is Easing
Easing is the curve that maps "progress of time" to "progress of change" in an animation. For example, when moving an element from 0px to 100px over 0.3 seconds, do you move it at a constant speed from start to finish, start slowly and accelerate, or move briskly and then ease to a stop? This distribution of speed is exactly what easing is.
Objects in the real world do not jump to top speed instantly. Things at rest gradually accelerate, and moving things gradually decelerate to a stop. Reproducing this physical sense of speed on screen makes animation feel "natural and pleasant." Conversely, motion at a constant speed throughout feels mechanical and somehow dull.
In CSS, you specify easing with the transition-timing-function and animation-timing-function properties. Several common keywords are provided, and with the cubic-bezier() function you can freely design any pacing curve you like.
Common Keywords: ease / linear / ease-in-out
First, get familiar with the keywords CSS provides out of the box. Internally, each of these corresponds to a specific cubic-bezier.
| Keyword | Motion characteristics |
|---|---|
| linear | Constant speed throughout. Mechanical, flat impression |
| ease | Starts slowly, accelerates, eases to a gentle stop (default) |
| ease-in | Starts slowly and gradually accelerates |
| ease-out | Starts briskly and decelerates to a stop |
| ease-in-out | Starts slowly, accelerates, then decelerates again at the end |
linear progresses at the same speed from start to finish. It suits cases where you want consistency over naturalness, such as a continuously rotating loader or a blink. ease is the default when nothing is specified, and it looks reasonably natural in many situations.
A handy thing to remember is the pairing "in = the start, out = the finish." ease-in starts slowly, and ease-out finishes slowly. It is effective to choose by direction: ease-out suits elements entering the screen, while ease-in suits elements leaving it. ease-in-out, slow at both ends and fast in the middle, is the most balanced motion.
What the Four cubic-bezier Values Mean
When you want to create custom pacing that the standard keywords cannot express, you use cubic-bezier(). The syntax takes four numbers, as follows.
cubic-bezier(x1, y1, x2, y2)
These four numbers represent the coordinates of two control points. (x1, y1) is the first control point and (x2, y2) is the second. To picture it easily, think of the horizontal and vertical axes like this.
- Horizontal axis (x) = progress of time: 0 is the start, 1 is the end. x1 and x2 must be within the 0–1 range.
- Vertical axis (y) = progress of change: 0 is the starting state, 1 is the completed state. y1 and y2 may go beyond 0–1 (negative or above 1 is allowed).
The curve always runs from the start point (0, 0) to the end point (1, 1), and the two control points pull its shape along the way. When y goes outside 0–1, you can express a "springy" motion that overshoots and comes back. To see exactly how the curve changes as you adjust the numbers, you can understand it at a glance by dragging the handles in the cubic-bezier Generator.
Incidentally, the standard keywords can also be written in this form. For example, ease equals cubic-bezier(0.25, 0.1, 0.25, 1.0), ease-in-out equals cubic-bezier(0.42, 0, 0.58, 1.0), and linear equals cubic-bezier(0, 0, 1, 1).
How Control Points Relate to the Curve
The trick to grasping cubic-bezier is to imagine that "the control points are pulling the curve." The curve connects the start and end points, but its slope in between is drawn toward the control points. A steep slope means "fast," and a gentle slope means "slow."
The first control point sets the start
The first control point (x1, y1) mainly sets the tone of the start (the early part). Making y1 small (near 0 or negative) means little change early on, that is, it starts slowly. This is ease-in-like motion. Conversely, a large y1 makes it lurch into motion right away.
The second control point sets the finish
The second control point (x2, y2) mainly sets the tone of the finish (the late part). Setting y2 near 1 or above 1 makes the change settle down at the end, that is, it stops slowly (ease-out-like). Pushing y2 above 1 and then coming back creates an "overshoot," where it passes the target once and returns, giving a bouncy impression.
cubic-bezier(0.68, -0.55, 0.27, 1.55)
As in the example above, making y1 negative and y2 above 1 produces a spring (bounce) like motion: it pulls back slightly, springs forward, then overshoots and returns at the end. You will learn the relationship between the numbers, the curve, and the actual motion far faster by moving the handles and watching the preview in the cubic-bezier Generator than by reasoning it out in your head.
How to Create Natural Motion
Animations that feel "natural and pleasant" share a few common techniques.
- Slow at the end (lean toward ease-out): The eye tends to focus on the moment of stopping. Decelerating gently at the end gives a careful, refined impression. ease-out-style is a safe default for most UI.
- Avoid linear (except for rotation): Constant-speed movement looks mechanical. Almost always add easing to decorative motion.
- Keep the duration short: For UI response, around 0.15–0.3 seconds feels comfortable. Motion that is too long becomes stressful instead.
- Do not overdo it: Overshoot and bounce are effective, but avoid overusing them. They shine when reserved for key moments.
Easing works the same way when you animate changes in color or gradients. For instance, when you want a button background gradient to change smoothly on hover, build the base gradient in the CSS Gradient Generator and combine its change with easing such as ease-out for an elegant finish.
How to Specify It in transition / animation
Finally, let us confirm how to write it in actual CSS. There are mainly two places to specify it: transition and animation.
Specifying it in transition
transition is the mechanism that smoothly animates a change when state changes (such as a hover or adding a class). You write the easing in the timing-function part.
transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55);
This means "change transform over 0.3 seconds along the specified spring-like curve." Instead of the shorthand, you can also specify it separately, like transition-timing-function: ease-out;.
Specifying it in animation
The idea is the same for animation using keyframes; you specify the easing with animation-timing-function.
animation: slidein 0.4s ease-out forwards;
Easing is not a flashy decoration but an unsung hero that raises the quality of your UI. Start by playing with the curve in the cubic-bezier Generator to get a feel for the motion, then paste it into your transition or animation. Once the meaning of the numbers clicks, you will be able to design any pacing you imagine. Pairing it with the CSS Gradient Generator to set up the visual base lets you raise the polish from both motion and decoration.
Please note that this article is intended to provide general information. CSS specifications and browser support can change, so make your decision after checking the latest official documentation when implementing.
FAQ
What is easing?
Easing is the curve of speed distribution (pacing) that maps the progress of change to the progress of time in an animation. It decides whether to move at a constant speed, start slowly and accelerate, or move briskly and decelerate at the end. In CSS you specify it with transition-timing-function or animation-timing-function.
What is the difference between ease, linear, and ease-in-out?
linear moves at a constant speed throughout for a mechanical feel, while ease (the default) starts slowly, accelerates, and eases to a gentle stop. ease-in starts slowly, ease-out finishes slowly, and ease-in-out is slow at both ends and fast in the middle, the most balanced motion. Remember in = the start, out = the finish.
What do the four numbers in cubic-bezier represent?
The four values in cubic-bezier(x1, y1, x2, y2) represent the coordinates of two control points. The horizontal axis x is the progress of time (0 is start, 1 is end), and x1 and x2 must be within 0–1. The vertical axis y is the progress of change, and y1 and y2 can go beyond 0–1; values above 1 or negative create springy motion that overshoots and returns.
Any tips for creating natural animations?
Basing your motion on ease-out style, which decelerates gently at the end, gives a careful, refined impression. Avoid linear for decorative motion and add easing instead, and keep the duration short, around 0.15–0.3 seconds. Overshoot and bounce are effective, but use them sparingly for key moments rather than everywhere.
Can I use the cubic-bezier Generator entirely in the browser? Is it free?
Yes. WAZA TOOLS' cubic-bezier Generator runs entirely in your browser, so what you enter is never sent to or stored on a server. It works on smartphones too, and you can adjust easing curves and export CSS code as many times as you like, for free.