UI motion guidance for hover and press feedback, toggles, toasts, drawers, modals, list transitions, and shared-element interactions.
Real-world examples not captured yet
This skill shows a gallery of live HTML demos (CDN libraries welcome — GSAP, Three.js, etc.) rendered inline via srcdoc.
Skill markdown
# 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 `transform` and `opacity` only — they are GPU-composited (no layout/paint). Avoid animating `width/height/top/left`; use `scale` or layout animation instead.
- Give **instant** press feedback: `scale: 0.96` on 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 is `cubic-bezier(0.34, 1.56, 0.64, 1)`; standard move `cubic-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
```jsx
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. `damping: 12`).
### Enter / exit with AnimatePresence
Exit animations require `AnimatePresence` wrapping conditionally-rendered children, each with a stable `key`.
```jsx
import { AnimatePresence, motion } from "motion/react";
<AnimatePresence>
{open && (
<motion.div
key="panel"
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 8 }}
transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}
/>
)}
</AnimatePresence>
```
For toasts/lists, use `mode="popLayout"` so removed items don't hold space while exiting.
### Layout animation (the superpower)
`layout` automatically animates any layout change (position/size) using transforms — perfect for reordering, expanding cards, and grid<->list.
```jsx
<motion.li layout transition={{ type: "spring", stiffness: 500, damping: 40 }} />
```
Shared-element transition across components: give two elements the same `layoutId` and Framer Motion animates between them as one mounts and the other unmounts.
```jsx
{!open && <motion.div layoutId="card" onClick={() => setOpen(true)} />}
<AnimatePresence>
{open && <motion.div layoutId="card" />} {/* "magic moves" from the source */}
</AnimatePresence>
```
Gotcha: a plain `layout` element distorts `border-radius` and text during scale. Add `layout` to direct children that should counter-scale, and prefer `borderRadius`/`boxShadow` as motion values, or use `layout="position"` to animate position only.
## Pure CSS path (no JS, including discrete properties)
Modern CSS can animate enter/exit and even `display` toggles without a library.
```css
.toast {
transition: opacity 0.2s ease, transform 0.2s ease;
/* allow animating to/from display:none and from initial render */
transition-behavior: allow-discrete;
}
.toast[hidden] { display: none; }
/* animate FROM these values on first render / when entering */
@starting-style {
.toast { opacity: 0; transform: translateY(8px); }
}
```
`@starting-style` defines the "before-open" values so an element animates in on first appearance; `transition-behavior: allow-discrete` lets `display` (and `overlay` for popovers/dialogs) participate so exit animations run before the element is removed. Baseline in Chrome/Edge/Safari; provide a no-animation fallback for older browsers.
Always include a reduced-motion guard:
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
## State, not just decoration
Loading → success → error should be one continuous motion (e.g. a button morphs spinner → checkmark), not a jump cut. Keep the element mounted and animate between states so the eye tracks the same object.
## Deliver & verify (standalone HTML)
> **Packaged helper** (`scripts/`): `scripts/seek-shot.sh anim.html 0 1.5 3` freezes the `?t=N` harness and screenshots each moment; `scripts/contact-sheet.sh sheet.png frame-*.png` tiles them for one-glance review. See `scripts/README.md`.
For a self-contained
…More from iart-ai
- 60fps AnimationWeb animation performance guidance for avoiding layout thrashing and reaching smooth 60/120fps motion with compositor-friendly techniques.
- Accessible AnimationTiered reduced-motion patterns for CSS, GSAP, Framer Motion, Lenis, and other web animation systems.
- Ascii AnimationThis skill should be used when the user asks to "make an ASCII animation", "build a terminal/CLI intro or loader", "convert an image or video to ASCII art", "add an ASCII shader/post-effect to a canvas or Three.js scene", "create retro/hacker text-character motion", or "animate text characters with a brightness ramp". Covers generative ASCII fields, image/video/3D-to-ASCII, and animated character art for both web and terminal.
- GlassmorphismThis skill should be used when the user asks to "add a glassmorphism effect", "frosted glass UI", "Apple liquid glass style", "frosted blur card", "translucent glass panel animation", "make a frosted nav bar", "build a glass modal/dialog", "animate a glass card on hover", or "add a refracting liquid-glass hero". Covers frosted translucent panels with backdrop-filter blur, edge/specular highlights, SVG liquid-glass refraction, motion on hover/scroll/enter, and accessible reduced-transparency fallbacks.
- GSAP WebGSAP guidance for code-driven web motion, including timelines, ScrollTrigger, SplitText, Flip, and smooth-scroll synchronization.
- Lottie AnimationLottie and dotLottie integration guidance for playback control, interactivity, runtime theming, and cross-platform export workflows.