Skip to content
ExamsLibraryFor agentsConnect your agent

Easing curves

beginner·7 min·Markdown for agents

What this lesson teaches

Pick the right easing curve for anything that moves, and know why ease-out makes the same animation feel faster.

  1. 1The decision order
  2. 2Custom curves beat the built-ins
  3. 3Curve and duration go together
  4. 4A note on writing it down

Open both dropdowns at once. They take exactly the same 250 milliseconds. One of them feels sluggish.

Newest
Oldest
Most replies
Unread first
ease-out (strong)0.23, 1, 0.32, 1
Newest
Oldest
Most replies
Unread first

Same duration on both sides. The right one feels faster because it moves the moment you click.

Same menu, same duration. Only the curve differs. Try slow-mo to see why.

The difference is the : how the speed changes during the animation. The left one uses , which starts slowly and speeds up. The right one uses , which moves most of the way at once and spends the rest of its time settling.

When you click, your eye goes straight to where the menu should appear. Ease-out puts something there in the very first frames. Ease-in makes you watch almost nothing happen, right at the moment you're paying the most attention. Never use ease-in on UI, exits included.

The decision order

You don't need to memorise curves. You need one rule per situation:

What's happeningCurve
Something entering or leaving (menu, toast, modal)ease-out
Something already on screen moving from A to B (a tab indicator)ease-in-out
A hover or a color changeease
Constant motion: a progress bar, a marquee, a hold-to-confirm filllinear
Not sureease-out

A drag, a flick or anything your finger is steering doesn't use a curve at all. It uses a spring, which gets its own lesson.

Custom curves beat the built-ins

CSS ships ease, ease-in, ease-out and ease-in-out. They were fine defaults a decade ago; today they read as "nobody chose this". A lets you write your own curve as four numbers, and a slightly stronger curve is most of what makes motion feel deliberate.

time →finishedcubic-bezier(0.23, 1, 0.32, 1)

Anything entering or leaving: dropdowns, popovers, toasts, modals.

Pick a curve to see its shape and watch the ball run it. The red one is the one to avoid.

Here is a small set worth keeping as tokens, mostly from Emil Kowalski's practice:

:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);        /* menus, popovers, toasts, modals */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);    /* on-screen travel, tab indicators */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);     /* sheets and drawers from an edge */
  --ease-out-soft: cubic-bezier(0.25, 1, 0.5, 1);    /* gentler hovers and menus */
  --ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);    /* overshoots: playful moments only */
}

Read the curve like a graph: time runs left to right, progress bottom to top. A steep start means it moves early. A number above 1 (like the 1.56 in back-out) means it shoots past the end and settles back, which is cute on a sticker and wrong on a delete dialog.

Curve and duration go together

A beautiful curve on the wrong duration looks worse than a plain ease-out on the right one. Tune them as a pair, which is the next lesson. Need a curve that isn't on the list? Take one from easing.dev or easings.co rather than hand-rolling four numbers.

✕ Before

.menu {
  transition: all 300ms ease-in;
}

✓ After

.menu {
  transition:
    opacity 200ms var(--ease-out),
    transform 200ms var(--ease-out);
}

Three fixes in one line: ease-out instead of ease-in, a named list of properties instead of all, and a shorter duration.

A note on writing it down

Small conventions make motion CSS easier to read and review. They come from Ben DC's frontend guidelines:

  • Pick one time unit and stick to it. This course uses milliseconds (200ms) everywhere, because they match JavaScript timers and design tokens. Mixing 200ms and 0.2s in one file is the actual bug.
  • Rotate in turns. rotate(0.25turn) is a quarter turn, rotate(1turn) a full spin. Keep degrees for arbitrary angles like 14deg.
  • Unitless line-heights, rem for things that should scale with the reader's font size and px for hairlines.
  • Avoid !important; it usually means a specificity fight the cascade should settle.

When you join an existing codebase, its conventions win. These are for when you're starting fresh.

Fix the easing· for your agent
Audit the CSS transitions and animations in this project. Replace any ease-in on UI with ease-out. Use these tokens: --ease-out: cubic-bezier(0.23, 1, 0.32, 1) for things entering or leaving, --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1) for things moving across the screen, --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1) for sheets. Use linear only for progress. Name the properties in every transition instead of "all", and keep durations in milliseconds.

Quick check

A dropdown uses transition: opacity 250ms ease-in. A user says it feels slow. What's the best first fix?

What this lesson builds on and leads to, across every course.

  • Briefs that work
  • Words matter
  • Routing the job