# Easing, explained: why good motion feels natural

[Canonical HTML page](https://gradiently.design/guide/easing)

The same movement can feel clumsy or effortless depending on one setting. That setting is easing, and a few simple rules cover nearly every case.

## The short version

- Easing describes how the speed of a movement changes over its duration, rather than staying constant from start to finish.
- Ease-out starts fast and slows down, which suits things entering; ease-in starts slowly and speeds up, which suits things leaving.
- Linear motion, at constant speed, looks mechanical for single moves but is right for continuous loops and rotations.
- A cubic-bezier curve defines any easing with two control points, and values outside 0 to 1 create overshoot.
- Springs describe motion with physical settings such as stiffness and damping, and CSS can approximate them with the linear() function.

**Easing** is how the speed of a movement changes while it plays. Without easing, an object moves at one constant speed and stops dead, which looks mechanical. With easing, it accelerates and decelerates the way real things do: a drawer slides out fast and settles, a ball speeds up as it falls. Choosing the right easing is the quickest way to make any animation feel natural.

## What easing looks like

Animators draw easing as a spacing chart: where an object sits at equal steps in time. When the marks are evenly spaced, the speed is constant. When they bunch up, the object is moving slowly; when they spread apart, it is moving fast. Here are the four basic easings, each showing eleven equal moments of the same movement from left to right.

- Linear: even spacing: `linear-gradient(90deg, #f9a8d4 0% 1.2%, #1e1b4b 1.2% 9.4%, #f9a8d4 9.4% 10.6%, #1e1b4b 10.6% 19.4%, #f9a8d4 19.4% 20.6%, #1e1b4b 20.6% 29.4%, #f9a8d4 29.4% 30.6%, #1e1b4b 30.6% 39.4%, #f9a8d4 39.4% 40.6%, #1e1b4b 40.6% 49.4%, #f9a8d4 49.4% 50.6%, #1e1b4b 50.6% 59.4%, #f9a8d4 59.4% 60.6%, #1e1b4b 60.6% 69.4%, #f9a8d4 69.4% 70.6%, #1e1b4b 70.6% 79.4%, #f9a8d4 79.4% 80.6%, #1e1b4b 80.6% 89.4%, #f9a8d4 89.4% 90.6%, #1e1b4b 90.6% 98.8%, #f9a8d4 98.8% 100%)`
- Ease-in: slow start, fast end: `linear-gradient(90deg, #f9a8d4 0% 2.3%, #1e1b4b 2.3% 5.6%, #f9a8d4 5.6% 6.8%, #1e1b4b 6.8% 12.4%, #f9a8d4 12.4% 13.6%, #1e1b4b 13.6% 20.9%, #f9a8d4 20.9% 22.1%, #1e1b4b 22.1% 30.9%, #f9a8d4 30.9% 32.1%, #1e1b4b 32.1% 42.3%, #f9a8d4 42.3% 43.5%, #1e1b4b 43.5% 54.9%, #f9a8d4 54.9% 56.1%, #1e1b4b 56.1% 68.6%, #f9a8d4 68.6% 69.8%, #1e1b4b 69.8% 83.3%, #f9a8d4 83.3% 84.5%, #1e1b4b 84.5% 98.8%, #f9a8d4 98.8% 100%)`
- Ease-out: fast start, gentle stop: `linear-gradient(90deg, #f9a8d4 0% 1.2%, #1e1b4b 1.2% 15.5%, #f9a8d4 15.5% 16.7%, #1e1b4b 16.7% 30.2%, #f9a8d4 30.2% 31.4%, #1e1b4b 31.4% 43.9%, #f9a8d4 43.9% 45.1%, #1e1b4b 45.1% 56.5%, #f9a8d4 56.5% 57.7%, #1e1b4b 57.7% 67.9%, #f9a8d4 67.9% 69.1%, #1e1b4b 69.1% 77.9%, #f9a8d4 77.9% 79.1%, #1e1b4b 79.1% 86.4%, #f9a8d4 86.4% 87.6%, #1e1b4b 87.6% 93.2%, #f9a8d4 93.2% 94.4%, #1e1b4b 94.4% 97.7%, #f9a8d4 97.7% 100%)`
- Ease-in-out: gentle at both ends: `linear-gradient(90deg, #f9a8d4 0% 2.6%, #1e1b4b 2.6% 7.6%, #f9a8d4 7.6% 8.8%, #1e1b4b 8.8% 18.1%, #f9a8d4 18.1% 19.3%, #1e1b4b 19.3% 32.6%, #f9a8d4 32.6% 33.8%, #1e1b4b 33.8% 49.4%, #f9a8d4 49.4% 50.6%, #1e1b4b 50.6% 66.2%, #f9a8d4 66.2% 67.4%, #1e1b4b 67.4% 80.7%, #f9a8d4 80.7% 81.9%, #1e1b4b 81.9% 91.2%, #f9a8d4 91.2% 92.4%, #1e1b4b 92.4% 97.4%, #f9a8d4 97.4% 100%)`

Spacing charts calculated from the CSS curves. Each pink line is the object's position at one of eleven equal moments. Bunched lines mean slow, spread lines mean fast.

## The four easings you actually need

CSS names five basic curves, and design tools use the same ideas under similar names. Four of them cover nearly every job. The fifth, `ease`, is the browser default: a curve that starts fairly fast and settles gently, much like a softer ease-out.

| Easing | CSS curve | Use it for |
| --- | --- | --- |
| Ease-out | `cubic-bezier(0, 0, 0.58, 1)` | Things entering or appearing: menus, cards, headlines |
| Ease-in | `cubic-bezier(0.42, 0, 1, 1)` | Things leaving or disappearing |
| Ease-in-out | `cubic-bezier(0.42, 0, 0.58, 1)` | Things moving from one place to another on screen |
| Linear | `cubic-bezier(0, 0, 1, 1)` | Continuous loops, rotations, progress bars, background drift |

The CSS keyword values. Many teams use slightly stronger custom curves, but the roles stay the same.

The logic is physical. Something arriving should already be moving when it appears, then settle, so it eases out. Something leaving should gather speed as it goes, so it eases in. Linear is wrong for a single move, but right for anything continuous: a loop that eases at its ends seems to hesitate every time it repeats, as [seamless loops](https://gradiently.design/guide/seamless-loop-video) explains.

## How cubic-bezier curves work

Every CSS easing curve is drawn between two fixed points, the start (0, 0) and the end (1, 1). A `cubic-bezier()` adds two control points that bend the curve. The horizontal axis is time and the vertical axis is progress. The time values must stay between 0 and 1, but progress values can go beyond, which makes a movement overshoot its target and come back.

```css
/* A stronger ease-out than the keyword: quick start, long gentle settle */
.card-enter {
  transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Overshoot: the second y value above 1 carries it past, then back */
.badge-pop {
  transition: transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Exits: shorter and easing in */
.card-leave {
  transition: transform 200ms cubic-bezier(0.4, 0, 1, 1);
}
```

Custom curves in CSS. Keep overshoot for small, playful moments; on large panels it feels wobbly.

MDN's reference to [easing functions](https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function) lists every form CSS accepts, including `steps()` for frame-by-frame movement.

## Springs: easing from physics

A spring doesn't use a fixed curve and duration. You describe the physics instead, usually stiffness (how strongly it pulls towards the target), damping (how quickly it calms down) and mass, and the motion follows. Stiff, well-damped springs feel snappy and precise; loose, lightly damped ones bounce. Springs are popular in app interfaces because they respond naturally when a movement is interrupted halfway.

Many animation libraries offer springs directly. In plain CSS, the `linear()` function can approximate one by listing points along its path, which modern browsers support.

```css
/* A simple spring-like settle: past the target, back, then rest */
.sheet-open {
  transition: transform 500ms
    linear(0, 0.6 20%, 1.08 45%, 0.98 70%, 1);
}
```

`linear()` joins the points with straight segments. More points give a smoother curve; generators can calculate them from spring settings.

## Easing and duration work together

The same curve feels different at different lengths. An ease-out over 150 milliseconds reads as a crisp snap; over 800 it reads as a slow glide. Match both to the distance and the job. [Motion design principles](https://gradiently.design/guide/motion-design-principles) has typical durations.

### Common mistakes

- Linear motion for a menu or card entering
- Ease-in on things appearing, so they start sluggishly
- The same long duration for small and large movements
- Bouncy overshoot on everything
- Easing at the ends of a continuous loop

### Better

- Ease-out for anything arriving
- Ease-in, slightly shorter, for anything leaving
- Short for small moves, longer for bigger ones
- Overshoot saved for small, playful moments
- Linear for loops, so they never hesitate

## Easing in JavaScript, design tools and video

The same curves work outside CSS. In JavaScript, the Web Animations API takes a CSS easing string. Design and video tools use the same ideas under names such as ease in, ease out and ease in and out, usually with a graph editor for custom curves and, in many prototyping tools, spring presets.

```js
const card = document.querySelector('.card')

card.animate(
  [
    { transform: 'translateY(24px)', opacity: 0 },
    { transform: 'translateY(0)', opacity: 1 },
  ],
  { duration: 300, easing: 'cubic-bezier(0.16, 1, 0.3, 1)', fill: 'both' },
)
```

An eased entrance with the Web Animations API, using the same curve as the CSS above.

Whatever the curve, some people prefer less motion. Honour their setting by shortening or removing movement; [reduced motion](https://gradiently.design/guide/reduced-motion) shows how. And for looping backgrounds, where linear is usually right, see [animated gradient backgrounds](https://gradiently.design/guide/animated-gradient-background).

## FAQ

### What is easing in animation?

Easing is the way the speed of a movement changes over its duration. Instead of moving at a constant speed, an eased movement accelerates, decelerates or both, which looks more natural.

### What is the difference between ease-in and ease-out?

Ease-in starts slowly and speeds up, which suits things leaving. Ease-out starts quickly and slows down, which suits things entering.

### When should I use linear easing?

For continuous motion such as loops, rotations, progress bars and slow background drift. For single movements it looks mechanical.

### What does cubic-bezier mean in CSS?

It defines an easing curve with two control points between the fixed start and end. Time values stay between 0 and 1, while progress values beyond that range create overshoot.

### What is spring animation?

Motion described by physical settings such as stiffness, damping and mass instead of a fixed curve. CSS can approximate springs with the linear() easing function.
