Animate icon swaps

Crossfade icons with opacity, scale and blur, not an instant swap.

From design-motion-principles, cookbook §5 Contextual icons.

Which one do you notice?

Press Copy both, then tap each icon alone.

Instant swapBad
INV-2026-1042
{copied ? <Check /> : <Copy />}
Opacity + scale + blurGood
INV-2026-1042
opacity 0→1scale 0.8→1blur 4px→0mode="wait"
.icon {
  grid-area: 1 / 1;
  opacity: 0; transform: scale(0.8); filter: blur(4px);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out),
              filter 200ms var(--ease-out);
}
.icon.on {
  opacity: 1; transform: scale(1); filter: blur(0);
  transition-delay: 200ms; /* mode="wait": enter after the exit */
}

What each property adds

Toggle properties, then press the play button.

Play / pauseYour mix
opacity, scale, blur · wait · 400ms

Loading → done

Press Save in either pane; it resolves after 1.2s.

Instant swapBad
{saving ? <Spinner /> : <Check />}
Animated swapGood
opacityscale 0.8→1blur 4px→0200ms + 200ms
/* Rotate an inner element so the wrapper can scale and blur. */
.icon .spin { animation: spin 700ms linear infinite; }

@media (prefers-reduced-motion: reduce) {
  .icon, .icon.on { transform: none; filter: none; transition-property: opacity; }
}

Why it matters, pros and cons

Why it matters

An instant swap lasts one frame under the cursor. Motion is what the eye catches.

Pros

  • Confirms in place, no toast needed.
  • Cheap: opacity, transform, a tiny blur.
  • Transitions interrupt cleanly on rapid clicks.

Cons

  • mode="wait" doubles the time; keep halves short.
  • High-frequency toggles should be faster or instant.
  • Blur repaints; avoid it on large elements.