Skip to content
Motion & micro-interactionsLesson 1 of 8Beginner9 min

Motion principles

Borrowed from classic animation: timing, anticipation, follow-through, and staging turn a mechanical move into one that reads as intentional.

Kept on this device only.

In one line: the same slide can read as a robotic teleport or a deliberate, physical move — what separates them is a handful of old animation principles, each worth only a few lines of code.

What it is

The classic principles of animation are a small vocabulary for making motion feel intentional. Four of them carry most of the weight on a screen. Timing is how speed is distributed across a move: an object that starts fast and eases to a stop feels responsive, while a constant, linear crawl feels mechanical. Anticipation is a tiny preparatory move in the opposite direction — a wind-up — that warns the eye something is about to happen. Follow-through lets connected parts settle slightly out of sync, so a group of elements behaves like linked objects instead of one rigid block. Staging directs attention: the thing that is changing becomes the clear focus, and everything else recedes.

None of these are about decoration. They are about legibility — making a change easy to read at a glance.

Why it matters

A plain state swap (here, then suddenly there) gives the eye no story. The viewer sees the result but misses the cause, so the interface feels abrupt and a little broken. The principles supply the missing cause-and-effect: timing says this is winding down, anticipation says this is about to move, follow-through says these things are attached, and staging says look here.

The payoff is perceived quality. Apply them with restraint and an interface reads as crafted and calm. Overdo any one and it backfires — heavy anticipation feels twitchy, slow follow-through feels laggy, aggressive staging feels theatrical. The skill is dialing each effect down until it is felt more than noticed.

See it

Live demo
Tweak it2
1
Switch principles to feel how timing, anticipation, and follow-through change a move.

How it works

Pick one move — a card sliding from left to right — and apply each principle to it in turn.

  1. Timing. Animate the slide with an ease-out curve (cubic-bezier(0, 0, 0.2, 1)) instead of linear. Most of the distance is covered in the first third of the duration, so the card feels like it is reacting to a force and coasting to rest. Linear motion, by contrast, looks machine-driven because nothing in the physical world moves at a perfectly constant speed and then stops dead.

  2. Anticipation. Before the card slides right, nudge it a few pixels left. That backward dip is a visual wind-up: it primes the eye for the larger move that follows. Keep it small — a 10–15px hint, not a full backswing — or the move starts to feel like a flinch.

  3. Follow-through. Give the card a trailing companion that animates with the same spring but a slightly later start. The follower arrives a beat behind the leader, which is what physically linked objects do. The lag is the whole effect; remove it and the pair snaps as one stiff unit.

  4. Staging. When the card moves, lift it (a small scale-up) and let the surrounding surface dim. Raising the contrast between the mover and its context is what staging means — you are not adding motion so much as removing competition for attention.

Across all four, you only ever animate transform and opacity. That keeps every frame off the layout path and lets the compositor do the work.

Build it

The four principles in vanilla CSS
/* Shared resting state. Animate transform/opacity only. */
.card {
  transform: translateX(0);
  transition: transform 500ms cubic-bezier(0, 0, 0.2, 1); /* TIMING: ease-out */
}
.card.is-moved {
  transform: translateX(150px);
}
 
/* ANTICIPATION: dip back, then slide forward (and overshoot a touch). */
.card.anticipate.is-moved {
  animation: anticipate 600ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
@keyframes anticipate {
  0%   { transform: translateX(0); }
  18%  { transform: translateX(-14px); }  /* wind-up */
  85%  { transform: translateX(158px); }  /* slight overshoot */
  100% { transform: translateX(150px); }
}
 
/* FOLLOW-THROUGH: a trailing element starts the same move slightly later. */
.follower {
  transform: translateX(0);
  transition: transform 500ms cubic-bezier(0, 0, 0.2, 1) 90ms; /* +90ms delay */
}
.follower.is-moved {
  transform: translateX(150px);
}
 
/* STAGING: the mover lifts and brightens, its context dims. */
.card.stage.is-moved { transform: translateX(150px) scale(1.12); }
.stage-backdrop.is-moved { opacity: 0.55; transition: opacity 350ms ease; }
 
/* Reduced motion: jump to the end state, no animation. */
@media (prefers-reduced-motion: reduce) {
  .card,
  .follower,
  .card.anticipate.is-moved,
  .card.stage.is-moved,
  .stage-backdrop.is-moved {
    transition: none;
    animation: none;
  }
}

Make it yours

Use the controls beside the demo above to change principle and strength — each change updates the example live.

Experiment in the playground

Reproduce it with an LLM

Reproduce it with an LLM

You are a senior front-end engineer who understands classic animation principles. Take a simple UI interaction — 'a card expands to a detail view when clicked' — and apply three motion principles to make it feel intentional: (1) ease/timing (start fast, settle gently), (2) anticipation (a tiny opposite move before the main one), and (3) follow-through (a secondary element lags slightly behind). Build it in React with the Motion library. Requirements: animate only transform and opacity; fully disable motion under prefers-reduced-motion: reduce; keep it keyboard-operable with a visible focus ring; keep the whole thing under ~450ms. Add a one-line comment naming the principle at each step. Return only the component code with imports.

Pitfalls & accessibility

Further reading

  • The original twelve principles of animation, for the source these screen-friendly four are adapted from.
  • Material and platform motion guidelines, for sensible default durations and easing curves to start from.