Anticipation

Tune anticipation, follow-through, and deformation to understand physical feedback.

Preview

Live preview

A small wind-up in the opposite direction before a move, hinting at what's about to happen.

Preview
Anticipation
Authoritative vocabulary

Definition and close-term distinctions

English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.

Canonical termanticipation

Anticipation

预备动作
Authoritative definition

A small wind-up in the opposite direction before a move, hinting at what's about to happen.

Chinese translation

动作开始前先向相反方向进行一小段蓄力,用来预示即将发生的运动。

Browse all 91 terms
Design contract

Decide before this motion ships

Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.

Purpose

Use opposite-direction anticipation, follow-through settling, and measured deformation to express direction, weight, and flexibility.

Frequency

Use for low-frequency object motion with physical meaning, compressing anticipation heavily for frequent UI feedback.

Trigger

Trigger from user-initiated movement, throwing, or state changes, with anticipation opposite the main travel.

Enter / exit

Wind up briefly before the main travel and settle with one decaying follow-through phase.

Interruptibility

Cancel remaining phases on interruption and retarget from current position and velocity.

Gesture and keyboard

Let gesture velocity influence main travel without delaying response, using a fixed brief anticipation for keyboard triggers.

Reduced-motion strategy

Remove wind-up, overshoot, and deformation, moving directly to the stable target or using a short fade.

Output

Copy into your interface

Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.

Updates with parameters
motion.css
.motion-demo.motion-demo--anticipation {
  position: relative;
  display: grid;
  place-items: center;
  width: min(100%, 34rem);
  min-height: 15rem;
  padding: 2rem;
  overflow: hidden;
  color: #18181b;
  background: #fafafa;
  border: 1px solid #e4e4e7;
  border-radius: 12px;
  isolation: isolate;
}

.motion-demo.motion-demo--anticipation *, .motion-demo.motion-demo--anticipation *::before, .motion-demo.motion-demo--anticipation *::after {
  box-sizing: border-box;
}

.motion-demo.motion-demo--anticipation .motion-surface {
  position: relative;
  display: grid;
  gap: 0.65rem;
  width: min(100%, 18rem);
  padding: 1.25rem;
  background: #ffffff;
  border: 1px solid #e4e4e7;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 10px 28px rgb(0 0 0 / 7%);
}

.motion-demo.motion-demo--anticipation .motion-line {
  display: block;
  width: 100%;
  height: 0.5rem;
  background: #e4e4e7;
  border-radius: 999px;
}

.motion-demo.motion-demo--anticipation .motion-line:last-child { width: 62%; }

.motion-demo.motion-demo--anticipation .motion-button {
  position: relative;
  min-height: 2.75rem;
  padding: 0.75rem 1.1rem;
  color: white;
  font: inherit;
  font-weight: 700;
  background: #18181b;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--anticipation .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }

.motion-demo.motion-demo--anticipation .motion-action-row {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.motion-demo.motion-demo--anticipation .motion-replay-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--anticipation .motion-pausable-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--anticipation button.motion-surface {
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.motion-demo.motion-demo--anticipation .motion-replay-button,
.motion-demo.motion-demo--anticipation .motion-undo-button,
.motion-demo.motion-demo--anticipation .motion-dismiss-button,
.motion-demo.motion-demo--anticipation .motion-pause-button {
  min-height: 2.75rem;
  padding: 0.65rem 0.9rem;
  color: #18181b;
  font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
  background: #ffffff;
  border: 1px solid #d4d4d8;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--anticipation .motion-replay-button:focus-visible,
.motion-demo.motion-demo--anticipation .motion-undo-button:focus-visible,
.motion-demo.motion-demo--anticipation .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--anticipation .motion-pause-button:focus-visible,
.motion-demo.motion-demo--anticipation [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--anticipation [data-swipe-target]:focus-visible {
  outline: 3px solid rgb(37 99 235 / 32%);
  outline-offset: 3px;
}

.motion-demo.motion-demo--anticipation .motion-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.motion-demo.motion-demo--anticipation .motion-ripple-ink {
  position: absolute;
  width: 12px;
  height: 12px;
  pointer-events: none;
  background: rgb(255 255 255 / 72%);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.95);
  opacity: 0;
}

.motion-demo.motion-demo--anticipation .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--anticipation .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--anticipation .motion-state--to { background: #18181b; color: white; }

.motion-demo.motion-demo--anticipation .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--anticipation .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--anticipation .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--anticipation svg { width: min(100%, 20rem); height: auto; }

.motion-demo.motion-demo--anticipation .motion-surface { animation: motion-anticipation 520ms cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes motion-anticipation { 0% { transform: none; } 18% { transform: translateX(-6px) scaleX(0.955); } 72% { transform: translateX(32px) scaleX(1.040); } 88% { transform: translateX(28px); } 100% { transform: translateX(32px); } }

@keyframes motion-anticipation-reduced-fade {
  from { opacity: 0.84; }
  to { opacity: 1; }
}

.force-reduced-motion .motion-demo.motion-demo--anticipation {
  animation: motion-anticipation-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}

.force-reduced-motion .motion-demo.motion-demo--anticipation *,
.force-reduced-motion .motion-demo.motion-demo--anticipation *::before,
.force-reduced-motion .motion-demo.motion-demo--anticipation *::after {
  animation: none !important;
  animation-delay: 0ms !important;
  animation-iteration-count: 1 !important;
  transition-property: opacity, color, background-color, border-color !important;
  transition-duration: 160ms !important;
  transition-delay: 0ms !important;
  scroll-behavior: auto !important;
}

.force-reduced-motion .motion-demo.motion-demo--anticipation .motion-button,
.force-reduced-motion .motion-demo.motion-demo--anticipation [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--anticipation [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--anticipation [data-spring-target] {
  transform: none !important;
}

.force-reduced-motion .motion-demo.motion-demo--anticipation .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--anticipation .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--anticipation .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .motion-demo.motion-demo--anticipation {
    animation: motion-anticipation-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
  }

  .motion-demo.motion-demo--anticipation *, .motion-demo.motion-demo--anticipation *::before, .motion-demo.motion-demo--anticipation *::after {
    animation: none !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-property: opacity, color, background-color, border-color !important;
    transition-duration: 160ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .motion-demo.motion-demo--anticipation .motion-button,
  .motion-demo.motion-demo--anticipation [data-reorder-item],
  .motion-demo.motion-demo--anticipation [data-swipe-target],
  .motion-demo.motion-demo--anticipation [data-spring-target] {
    transform: none !important;
  }

  .motion-demo.motion-demo--anticipation .motion-path { stroke-dashoffset: 0 !important; }
  .motion-demo.motion-demo--anticipation .motion-word--from { opacity: 0 !important; visibility: hidden; }
  .motion-demo.motion-demo--anticipation .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}
Review notes

Pre-delivery review

  • Review Anticipation, Follow-through, and Squash & stretch as distinct concepts.
  • Limit deformation so text and icons remain recognizable.
Accessibility

Keep information accessible

Reduced motion

Remove wind-up, overshoot, and deformation, moving directly to the stable target or using a short fade.

Parameters

Parameter reference

ParameterRange / optionsDefaultPurpose
duration300ms–1200ms520msUses a longer demo duration so the full change stays observable; immediate production UI feedback should stay under 300ms.
distance0px–80px32pxControls how far the element travels.
anticipation0%–40%18%Adjusts anticipation.
followThrough0%–30%12%Adjusts follow-through.
easeSoft / Snap / Calm / LinearSnapControls how velocity changes over time.