| Named easings |
|---|
| linear | cubic-bezier(0, 0, 1, 1) | Constant speed, mechanical, no acceleration. | Opacity and color fades, spinning indicators, progress that must track time exactly. Avoid for movement — it reads as robotic. |
| ease | cubic-bezier(0.25, 0.1, 0.25, 1) | Gentle accelerate then settle; the browser default for transitions. | Acceptable default when you have not chosen a curve. Slightly front-loaded, so it feels softer than ease-out on entrances. |
| ease-in | cubic-bezier(0.42, 0, 1, 1) | Starts slow, ends at full speed; departs with rising energy. | Exits and dismissals — the element accelerates away because the user already decided to close it. |
| ease-out | cubic-bezier(0, 0, 0.58, 1) | Starts fast, decelerates into place; the eye locks on easily. | Entrances and appearances — dropdowns, toasts, modal content. The safest single curve for UI that appears. |
| ease-in-out | cubic-bezier(0.42, 0, 0.58, 1) | Symmetric ramp up and ramp down; smooth at both ends. | Movement that stays on screen and reverses — panels sliding, toggles, page transitions between two visible states. |
| cubic-bezier() anatomy |
|---|
| x1 | 0.25 (first control point, x) | Horizontal pull of the first handle; how slowly the animation starts. | First of four parameters: cubic-bezier(x1, y1, x2, y2). Must stay within 0-1 — values outside the range are invalid and the declaration is dropped. |
| y1 | 0.1 (first control point, y) | Vertical pull at the start; early output below 0 delays visible motion. | Unclamped — any value is legal. Raising y1 above the line makes the property jump ahead early; lowering it creates a pull-back before motion begins. |
| x2 | 0.25 (second control point, x) | Horizontal pull of the second handle; how long the settle lasts. | Third parameter, also clamped to 0-1. Keep x2 greater than x1 or the curve doubles back in time, which CSS forbids. |
| y2 | 1 (second control point, y) | Vertical pull at the end; where the motion aims as it finishes. | Unclamped. y2 above 1 pushes output past the target at the tail; below 0 makes the element stop short then catch up. |
| Overshoot | y1 < 0 or y2 > 1 | The animated value passes beyond its start or end, then returns. | y outside 0-1 is the only way cubic-bezier() overshoots — e.g. cubic-bezier(0.34, 1.56, 0.64, 1). Use sparingly; overshoot on position can clip at container edges. |
| Clamped x rule | 0 ≤ x1, x2 ≤ 1 | Time cannot run backwards; only output can. | The horizontal axis is progress (0% to 100% of the duration), so x values outside 0-1 are rejected. The vertical axis is the property output and is free. Outside the 0-1 progress window the curve is extrapolated flat. |
| Common curve presets |
|---|
| ease-out-quint | cubic-bezier(0.22, 1, 0.36, 1) | Very fast start, long silky settle; premium and calm. | The workhorse entrance curve for menus, cards, and panels that appear. Pair with 200-300ms. |
| ease-out-expo | cubic-bezier(0.16, 1, 0.3, 1) | Nearly instant launch, extremely long deceleration; dramatic. | Hero reveals and large surfaces that must feel immediate. Needs a longer duration (300ms+) or the settle is cut off. |
| ease-out-cubic | cubic-bezier(0.33, 1, 0.68, 1) | Brisk start, moderate settle; neutral and unfussy. | General-purpose entrance when ease-out-quint feels too slow. Good default for hover-adjacent state changes at 150-200ms. |
| ease-out-back | cubic-bezier(0.34, 1.56, 0.64, 1) | Slides in, overshoots the target, springs back; playful. | Small delights — toggles, chips, badges, emoji-scale feedback. The 1.56 y2 is what creates the bounce past 100%. |
| ease-in-out-quint | cubic-bezier(0.83, 0, 0.17, 1) | Slow wind-up, fast middle, long settle; cinematic and heavy. | Large two-sided motion: page transitions, full-screen sheets, carousel slides at 400-600ms. |
| ease-in-out-cubic | cubic-bezier(0.65, 0, 0.35, 1) | Balanced accelerate-decelerate; smooth and symmetric. | Mid-size symmetric motion where ease-in-out (the keyword) is too mild — drawers, accordions, 250-350ms. |
| ease-in-out-back | cubic-bezier(0.68, -0.6, 0.32, 1.6) | Pulls back before moving, overshoots the landing; elastic character. | Attention-seeking transitions where a wind-up reads as intentional (game UI, onboarding). Both y values are outside 0-1, so it overshoots in both directions. |
| ease-in-quint | cubic-bezier(0.64, 0, 0.78, 0) | Long hesitation, then hard acceleration to the end; abrupt finish. | Exits that should feel decisive — dismissal of non-critical toasts and hints at 150-200ms. |
| ease-in-expo | cubic-bezier(0.7, 0, 0.84, 0) | Almost nothing, then gone; maximum hesitation. | Very short exits where the element should vanish with rising speed. y1 and y2 at 0 pin the start and end to the baseline. |
| ease-in-out-sine | cubic-bezier(0.37, 0, 0.63, 1) | Soft gentle arc, no hard edges; quiet. | Subtle ambient motion — background drift, slow opacity crossfades — where any visible acceleration would distract. |
| Enter vs exit guidance |
|---|
| Enter (appear) | ease-out family · 150-300ms | Fast in, glide to rest; the user's eye arrives with the element. | Anything appearing: dialogs, dropdowns, toasts, newly inserted rows. Deceleration gives the brain time to track the target. |
| Exit (dismiss) | ease-in family · 100-200ms | Accelerates away; the decision is already made, so do not linger. | Anything leaving that the user dismissed. Keep exits ~30% faster than the matching entrance — the result feels lighter. |
| Micro feedback | ease-out · 100-150ms | Immediate acknowledgment, no wait. | Hover states, presses, icon swaps. Under 100ms reads as instant; long durations here feel laggy. |
| Standard transition | ease-out · 150-300ms | The default perceptual window for UI motion. | Start at 200ms for most elements. Above 300ms users start waiting for the interface; reserve longer only for large surfaces. |
| Move vs fade | strong curve for move · gentler for fade | Position changes need shaping; opacity changes barely do. | Animate transform with a pronounced ease-out or ease-in-out; opacity and color are near-linear-friendly because the eye does not track them the same way. |
| Reduced motion | @media (prefers-reduced-motion: reduce) | Motion minimized or removed; vestibular safety. | Wrap non-essential transitions so they collapse to near-zero duration (or opacity-only). Required for accessibility — large movement triggers discomfort for some users. |
| Bounce & springs | cubic-bezier() cannot bounce | One curve crosses the target once at most per axis extreme. | A single cubic-bezier() cannot express multiple oscillations — use animation keyframes or a spring library when you need real multi-bounce physics. |