The difference between an interface that feels cheap and one that feels expensive is often motion. Not big, showy motion, but the small, well-timed responses that confirm an action and guide the eye. This guide covers micro-interactions and web animation: what they are, the principles behind motion that feels right, and how to build it without wrecking performance or accessibility.
What Micro-Interactions Are
A micro-interaction is a small, contained moment of feedback built around a single task: a button that depresses when clicked, a toggle that slides, a heart that fills when liked, a field that shakes on an invalid entry.
Every micro-interaction has the same anatomy. A trigger starts it (a click, hover, scroll, or system event), rules define what happens, feedback communicates the result visually, and loops and modes govern how it repeats or behaves over time. The purpose is never decoration alone; it is communication. A good micro-interaction answers a silent question: Did that work? Is something loading? What changed? When motion answers those questions instantly, the product feels responsive and considered.
Principles: Timing and Easing
Most amateur animation fails on two variables: it takes too long, and it moves at a constant speed. Getting timing and easing right fixes the majority of problems.
Timing
Duration should match the size and importance of the change.
- 100-200ms for small, frequent feedback like hover and button states. Anything slower feels laggy.
- 200-300ms for medium transitions like dropdowns, tooltips, and small panels.
- 300-500ms for larger movements like modals or full-page transitions.
Above roughly 500ms, motion starts to feel sluggish and gets in the user’s way. When in doubt, make it faster than feels right; users rarely complain that an interface is too responsive.
Easing
Real objects do not start and stop instantly, so linear motion reads as robotic. Easing curves fix this.
ease-out(fast start, slow finish) is the default for elements entering the screen; it feels snappy and natural.ease-in(slow start, fast finish) suits elements leaving the screen.ease-in-outworks for movement between two on-screen states.- Custom
cubic-bezier()curves let you dial in personality, and a slight overshoot can add a premium, springy feel.
The single fastest upgrade to any animation is to replace its default linear easing with an ease-out curve and shorten its duration.
CSS Transitions and Keyframes
Most micro-interactions need no JavaScript. CSS handles them with two tools.
A transition animates a property between two states, ideal for hover and focus:
.button {
background: var(--accent);
transition: transform 150ms ease-out, background 150ms ease-out;
}
.button:hover { transform: translateY(-2px); }
Transition specific properties, not all, so the browser only watches what changes. For multi-step or looping motion, reach for keyframes:
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.loading { animation: pulse 1s ease-in-out infinite; }
Keyframes drive loaders, attention pulses, and entrance sequences. Between transitions and keyframes, you can build the overwhelming majority of interface motion with zero runtime cost from a scripting library.
Scroll and Hover Effects
Two trigger types carry most of the perceived polish on modern sites: hover and scroll.
Hover effects reward exploration on pointer devices: a card lifting, an image zooming inside its frame, an underline drawing in from one side. Keep them subtle, fast, and reversible, and remember that hover does not exist on touchscreens, so never hide essential information or actions behind it.
Scroll effects animate elements as they enter the viewport. The modern, performant way to do this is the Intersection Observer API in JavaScript, or increasingly scroll-driven animations in pure CSS using animation-timeline: view(), which ties an animation’s progress to an element’s position in the viewport without any script. Use scroll reveals sparingly; a gentle fade-and-rise on the first appearance of a section feels elegant, while animating every paragraph turns reading into a chore.
Performance
Janky animation is worse than no animation. The key is understanding what the browser can animate cheaply.
The browser renders in stages: layout (geometry), paint (pixels), and composite (layering). Animating properties that trigger layout (width, height, top, left, margin) forces the browser to recalculate the page on every frame, which stutters. Instead, animate only the two properties the GPU handles on the compositor:
transform(for movement, scaling, and rotation)opacity(for fades)
Want to move something? Use transform: translateX(), not left. Want to resize? Use transform: scale(), not width. These run on the compositor thread and can hold a smooth 60fps. Add the will-change property sparingly to hint at upcoming animation, but remove it afterward, since overuse consumes memory. The goal is a consistent frame budget of about 16ms per frame.
Respecting prefers-reduced-motion
Animation is not universally welcome. For users with vestibular disorders, large or parallax motion can cause real nausea and dizziness. Operating systems expose a “reduce motion” setting, and the web honors it through a media query:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
The respectful pattern is to design the reduced-motion experience deliberately rather than just killing everything. Replace a sliding transition with a simple fade, or remove parallax while keeping a subtle state change. Honoring this preference is part of WCAG accessibility guidance, not an optional nicety, and it costs only a few lines of CSS.
When Animation Hurts UX
More motion is not better motion. Animation becomes a liability in several recognizable situations.
- It slows the user down. A 600ms transition the user sees fifty times a day is fifty interruptions. Frequent actions should be near-instant.
- It distracts from the task. Motion draws the eye, so animating something unimportant steals attention from what matters.
- It fires constantly. Effects that retrigger on every scroll or every keystroke create visual noise and erode trust.
- It hides feedback in flourish. If a loading spinner spins so stylishly that users cannot tell whether anything is actually happening, the animation has failed its one job.
The test is simple: does this motion help the user understand or complete their task? If the honest answer is “it looks cool,” cut it or tone it down. Restraint is what separates premium motion from a gimmick.
The Takeaway
Premium-feeling interfaces are built on small, purposeful motion. Treat each micro-interaction as feedback, not decoration, and get timing (under ~300ms for most) and easing (favor ease-out) right before anything else. Build it with CSS transitions and keyframes, animate only transform and opacity to stay at 60fps, and use scroll and hover effects with a light hand. Always honor prefers-reduced-motion, and ruthlessly cut animation that slows users down or distracts them. Done well, motion is felt more than noticed, and that quiet confidence is exactly what reads as premium.
