Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 5.3Intermediate ~19 min · shot 3 of 6

Choosing an Easing

In one line

Pick the curve by the job the motion does: arriving things use ease-out, leaving things ease-in, things moving between two places on screen ease-in-out, and endless motion linear. Lumen keeps one token for each.

0/6 · 0%

Think of it like this

A bus pulling into a stop brakes gently and stops where you stand. A bus leaving the stop pulls away slowly, then speeds up. A bus going between two stops speeds up, cruises, then slows. A bus on a ring road never stops. Each needs a different speed pattern for its job.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

ease-out
Fast at the start and slow at the end. For things that arrive.
ease-in
Slow at the start and fast at the end. For things that leave.
ease-in-out
Slow at both ends. For things that move between two places that are both on screen.
token
A named value kept in one place (here a CSS custom property such as --ease-out) so every component uses the same one.
responsiveness
How soon after an action the interface visibly reacts. A strong ease-out gets visible movement earlier in the same duration.

Step by step

01Run the four jobs

Run "Four jobs, four curves" and press Run the four jobs. Four rows move: enter (opacity and transform, --ease-out, 220 ms), exit (--ease-in, 120 ms), move (--ease-in-out, 400 ms) and loop (linear, endless).

02Read the enter and exit at 60 ms

Pause, press Go, and step to 60 ms. enter is already at 47.9 px of 60 and 0.80 opaque. exit is still 0.87 opaque: it has hardly begun to fade. At 110 ms exit is 0.40 and enter has all but arrived (57.7 px, 0.96).

03Read the move

move is at 14.4 px of 160 at 110 ms, 101.9 px at 220 ms, and arrives at 400 ms. Its graph is an S; loop says linear.

04Judge the Feel it pairs

Replay both sides of each pair and choose before you open the answer.

Try it yourself

  1. 1

    Swap the enter curve

    In "Four jobs, four curves" change the .go .enter rule's two var(--ease-out) to var(--ease-in). Press the button, pause, step to 60 ms: enter is at only 2.3 px of 60 and 4% opaque, against 47.9 px and 80% before. The same 220 ms now looks stuck at the start.

  2. 2

    Make the move linear

    Change the .go .move easing to linear and compare at 110 ms: move is now at 44 px (110/400 of 160) instead of 14.4 px, and it starts and stops abruptly. Switch back to var(--ease-in-out) for the real thing.

Code & diagrams

Four jobs, four curves

Tokens from tokens.css (Phase 2) drive each row. Press the button, then pause and step through the first 220 ms to compare how each job moves.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

loop easing: linear
Feel itA menu opening

The menu opens over 250 ms in both. Which feels better?

A A

Press Run to see the page.

B B

Press Run to see the page.
Play both, then choose:
Feel itThe same curve family, two strengths

A drawer slides in over 300 ms. Both use ease-out. Which feels better?

A A

Press Run to see the page.

B B

Press Run to see the page.
Play both, then choose:

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Linear on a modal

In "Four jobs, four curves" set .enter to transition: opacity 250ms linear, transform 250ms linear;, to stand in for a dialog that scales and fades in.

terminal
$ Press the button, pause, and step to 100 ms
── what you'll see ──
enter: 24 px of 60 and 0.40 opaque.
Measured at 100 ms of 250: linear is exactly 0.4 of the way. The Lumen ease-out, computed for the same moment, would be 0.92 (55 px).

Break #2

A slow exit

Change .go .exit to transition: opacity var(--dur-slow) var(--ease-in), transform var(--dur-slow) var(--ease-in);.

terminal
$ Press the button and step to 110 ms
── what you'll see ──
The exiting box has hardly changed: at 110 ms of 400 it is still 0.96 opaque.
Measured: the exiting box is 0.961 opaque at 110 ms (the curve is only 3.9% through).

Myth vs fact

Myth

Exits should use ease-out too, because users hate waiting.

Fact

Some teams use ease-out for everything user-triggered, and that is a valid choice. The rule here, ease-in for exits kept very short, is the classic one: it gives a feeling of leaving. Pick one rule and write it in the spec; do not mix them by feel.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    The tokens are not the keywords. --ease-in-out (0.65, 0, 0.35, 1) is flatter at both ends than CSS ease-in-out (0.42, 0, 0.58, 1), so the move seems to wait a little longer before it starts and after it ends. Judge it by stepping, not by the name.

Remember this

  1. 1

    The problem this solves: a team with no rule picks curves by mood. One card uses ease, another linear, a third a copied cubic-bezier from a blog. The page feels inconsistent and nobody can say why. A rule that maps job to curve makes every motion feel like it came from the same hand.

  2. 2

    Arriving: ease-out. Something that enters the screen, or appears after a click, should be quick at the start and settle at the end. It answers the click at once (the user sees movement within the first frame or two) and lands softly. Lumen's --ease-out is cubic-bezier(0.22, 1, 0.36, 1): 76% of the move is done after a quarter of the time. A menu that opens with ease-in does the opposite: for the first 60 ms of 220 it has moved only 4% of its way.

  3. 3

    Leaving: ease-in. Something that exits starts slowly, and speeds up as it goes, like a bus pulling away. The slow start costs a little responsiveness, so exits must be short: Lumen's --ease-in runs for --dur-fast (120 ms). At 60 ms of 120 the element has faded only 13.5%, and by 110 ms it has faded 60%.

  4. 4

    Moving between two places on screen: ease-in-out. An element that is already visible and goes from one position to another (a card sliding to a new slot, a slider thumb) accelerates and decelerates. The symmetrical curve --ease-in-out is cubic-bezier(0.65, 0, 0.35, 1); it is flatter at both ends than the keyword ease-in-out (at a tenth of the time it has moved 0.9% of the way, against 2%).

  5. 5

    Endless motion: linear. A spinner, a progress bar that follows real progress, a marquee: if the motion is continuous and each turn begins where the last ended, any easing makes it speed up and slow down at every lap. Use linear. Endless motion needs a way to stop (Topic 7.4) and a calm version for reduced motion.

  6. 6

    Use strong curves, and short durations. The built-in ease-out reaches 90% of its move at 74% of the time; Lumen's token reaches 90% at 37%. At a quarter of the time the built-in curve has moved 38% of the way and the token 76%. Product interfaces favour strong ease-out with short durations (150–300 ms); decorative or brand moments (a hero) may use slower, softer curves.

Explain it without notes

01

Which curve should a toast use to enter, and which to leave? Why?

02

Why is linear the right curve for a spinner but the wrong one for a dialog?

03

What is the problem with a long duration on ease-in?

Practice

01

Name the curve token and duration token for: a tooltip appearing, a tooltip disappearing, a card sliding to a new grid slot, and a loading bar tied to real progress.

02

Why does a 120 ms exit use --ease-in, when ease-in is slow at the start?

Done when you can

  • You can map arriving, leaving, moving and looping to a curve

  • You can say why Lumen's ease-out feels faster than the keyword, with numbers

  • You can name two mistakes: ease-in on an entrance, linear on a dialog

  • You can name the tokens for each job