Why easing matters more than duration
Nothing in the physical world starts or stops instantly, so linear motion reads as mechanical and cheap. Easing describes how an animation's rate changes over its duration, and it is what makes motion feel deliberate rather than computed.
The three basic shapes each carry meaning. ease-out starts fast and decelerates, which suits anything entering the screen — the element arrives with momentum and settles. ease-in starts slow and accelerates, which suits exits, since the element gathers speed as it leaves. ease-in-out does both and suits movement between two on-screen positions.
The most common mistake is using ease-in for entrances. An element that starts slowly and speeds up as it arrives feels sluggish at exactly the moment the user is waiting for it. For anything responding to interaction, ease-out is almost always the right default because the response begins immediately.
Bézier curves and springs
cubic-bezier() takes four numbers defining two control points, with the curve running from (0,0) to (1,1). The x axis is time and the y axis is progress. Values outside 0 to 1 on the y axis are permitted and produce overshoot — progress passing 1 and coming back — which is how bounce and anticipation effects are made. Values outside 0 to 1 on the x axis are invalid, since time cannot run backwards.
The named keywords are all cubic-beziers underneath: ease is (0.25, 0.1, 0.25, 1), ease-in is (0.42, 0, 1, 1), ease-out is (0, 0, 0.58, 1). Custom curves generally beat the defaults — the built-in ease in particular is a fairly weak curve, and something like (0.16, 1, 0.3, 1) produces a much more decisive deceleration.
Bézier curves are fixed-duration, which is their limitation. Spring physics instead derives motion from stiffness, damping and mass, so an interrupted animation continues naturally from its current velocity rather than jumping. That makes springs better for interactive, interruptible motion — dragging, dismissing, gestures — while curves remain fine for one-shot transitions. CSS has a linear() function that can approximate a spring by listing many sampled points.
Duration, properties and restraint
Duration should scale with distance and size. Small elements moving short distances want 150 to 200 milliseconds; larger movements 250 to 400. Beyond about 500 milliseconds, motion starts to feel slow, and interface animation over a second reads as an obstacle. Hover feedback should be very fast, around 100 milliseconds, because it responds to a deliberate action.
Animate only transform and opacity where you can. Both are handled by the compositor without triggering layout or paint, so they run smoothly even under load. Animating width, height, top, left or margin forces layout recalculation every frame and is the usual cause of janky animation — use a transform instead.
Always honour prefers-reduced-motion. For people with vestibular disorders, large or spinning motion can cause genuine nausea, and the media query lets you replace movement with a simple opacity change while keeping the interface comprehensible. Reduced motion means less motion, not no feedback.