- name
- micro-interaction
- description
- This skill should be used when the user asks to "add a hover/press effect", "animate a toggle or switch", "build an animated like button", "make a toast/snackbar slide in", "animate a drawer or modal", "animate list reordering or add/remove", "do a shared-element layout transition", or "polish UI feedback". Covers UI motion with Framer Motion (motion/react) and modern CSS.
- version
- 0.1.0
Micro-interactions (UI Motion)
Small, functional motion that makes an interface feel responsive and alive: hover/press/focus feedback, toggles, toasts, drawers, and list/layout animation. The goal is feedback and continuity, not decoration.
When to use
- Hover/press/focus feedback; toggles, checkboxes, like/heart buttons
- Toasts/snackbars, drawers, modals, tooltips, accordions (enter/exit)
- List add/remove/reorder; shared-element ("magic move") layout transitions
- Loading → success → error state transitions
Principles (apply to all of it)
- Duration: UI micro-interactions live in 100–250ms. Anything over ~400ms feels laggy for a click response.
- Animate
transformandopacityonly — they are GPU-composited (no layout/paint). Avoid animatingwidth/height/top/left; usescaleor layout animation instead. - Give instant press feedback:
scale: 0.96on tap with a fast spring. - Asymmetric timing: enter slightly slower (ease-out), exit faster (ease-in). Things should arrive gracefully and leave promptly.
- Respect
prefers-reduced-motion: gate non-essential motion; keep opacity changes, drop large movement. - Easing defaults: ease-out for entrances
cubic-bezier(0.16, 1, 0.3, 1); a tasteful overshoot iscubic-bezier(0.34, 1.56, 0.64, 1); standard movecubic-bezier(0.4, 0, 0.2, 1).
Framer Motion (motion/react) essentials
As of v11+, the package is imported as motion/react (the framer-motion name still works).
Gestures and springs
import { motion } from "motion/react";
<motion.button
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 0.96 }}
whileFocus={{ boxShadow: "0 0 0 3px rgba(59,130,246,.5)" }}
transition={{ type: "spring", stiffness: 400, damping: 30 }}
/>
Spring intuition: higher stiffness = faster; higher damping = less bounce. stiffness: 400, damping: 30 is a snappy UI default. For visible bounce, lower damping (e.g. ).