Animation timing and UX perception
1) Why timing is critical
Animation is not a "decoration," but a manipulation of perception time. Milliseconds affect:- a sense of instant response and trust in the system;
- clarity of cause and effect (from/to which the element has moved);
- fatigue and comfort in long sessions;
- accuracy of actions (especially on mobile and at high rates).
The rule: timing serves a purpose. If animation does not help to understand "what happened," it interferes.
2) Psychophysics and thresholds
Benchmarks for product UI:- ≤ 50 ms - echo input (print, click effect); seems instant.
- ≤ 100 ms - the first visual feedback by action (the button "pressed").
- 120-180 ms - hover/focus, soft state transition.
- 180-280 ms - modals/panels; perceived as a "natural" appearance.
- 300-500 ms - shared element, step forward progress.
- ≈ 1200-1600 ms - skeleton/shimmer cycle; longer - tiring.
3) Easing and weight curves
The element "with weight" starts faster and "sticks" at the end. Base curves:- Standard: 'cubic-bezier (0. 2, 0, 0. 2, 1) '- neutral "material" dynamics.
- Pressed: 'cubic-bezier (0. 4, 0, 1, 1) '- quick login, short click.
- Overlay out: 'cubic-bezier (0, 0, 0. 2, 1) '- soft output.
- Underlined accent (rare): 'cubic-bezier (0. 2, 0. 8, 0. 2, 1. 2)` с overshoot ≤ 8 px.
Weight optics: the larger the component (card, drawer), the longer the duration (+ 40-80 ms to the base).
4) Phases and choreography
Divide the movement into phases:1. Initiation (10-40ms): light fade/scale 0. 98→1 - start signal.
2. Transport (main phase): moving/opening.
3. Draft (20-60 ms): small brake, shadow/focus ring stabilization.
Cascade (stagger):- Lists: 20-40 ms/item, maximum 6-8 items in a row.
- Forms: no cascade; everything appears at the same time so as not to interfere with input.
Reversibility: "back" mirrors "forward" and faster by 15-30%.
5) Timings by interaction type
6) Perception of time: how to "accelerate" without real acceleration
Instant affordance: instant change of cursors/pressed style ≤ 100 ms even before the network.
Concealment of complexity: parallel downloads; background data pull-up before opening the panel.
Sense anchor: shared element and direction of motion reduce the cognitive cost of waiting.
Optimistic updates: UI is "ready" immediately, the server confirms or rolls back.
7) Fatigue and animation hygiene
Avoid endless pulsations; any cycle must be intermittent or disconnectable.
Do micro effects on arrays of elements (table, grid) without blur/box-shadow on each node.
Support'prefers-reduced-motion: reduce ': leave only fade ≤ 100ms or a static status switch.
css
@media (prefers-reduced-motion: reduce) {
{ animation: none! important; transition-duration:.01ms! important; }
}
8) Timing tokens (design system)
json
{
"motion": {
"duration": { "press": 90, "hover": 160, "focus": 160, "overlayIn": 240, "overlayOut": 180, "tab": 200, "shared": 280 },
"easing": {
"standard": "cubic-bezier(0. 2,0,0. 2,1)",
"accelerate": "cubic-bezier(0. 4,0,1,1)",
"decelerate": "cubic-bezier(0,0,0. 2,1)"
},
"stagger": { "listItem": 30, "maxItems": 8 }
}
}
Naming: 'motion. duration.{role}` и `motion. easing. {role} '- components and Figma are the same for the engine.
9) Implementation: CSS and Framer Motion
CSS presets:css
:root{
--dur-press:90ms; --dur-hover:160ms; --dur-overlay-in:240ms; --dur-overlay-out:180ms;
--ease-std:cubic-bezier(.2,0,.2,1);
--ease-acc:cubic-bezier(.4,0,1,1);
--ease-dec:cubic-bezier(0,0,.2,1);
}
.button{ transition: transform var(--dur-press) var(--ease-acc), box-shadow var(--dur-hover) var(--ease-std); }
.button:active{ transform: scale(.98); }
.modal-enter{ animation: modalIn var(--dur-overlay-in) var(--ease-std) both; }
.modal-exit { animation: modalOut var(--dur-overlay-out) var(--ease-dec) both; }
@keyframes modalIn{ from{opacity:0; transform:translateY(16px) scale(.98)} to{opacity:1; transform:none} }
@keyframes modalOut{ from{opacity:1} to{opacity:0; transform:translateY(8px) scale(.99)} }
Framer Motion (example of a modal):
tsx import { motion, AnimatePresence } from "framer-motion";
export function Modal({ open, children }) {
return (
<AnimatePresence>
{open && (
<motion. div initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}}
transition={{duration:.18, ease:[0. 2,0,0. 2,1]}} className="fixed inset-0 bg-black/50">
<motion. div initial={{y:16, scale:.98, opacity:0}}
animate={{y:0, scale:1, opacity:1, transition:{duration:.24, ease:[0. 2,0,0. 2,1]}}}
exit={{y:8, scale:.99, opacity:0, transition:{duration:.18, ease:[0,0,0. 2,1]}}}
className="m-auto max-w-lg rounded-2xl bg-white p-6">
{children}
</motion. div>
</motion. div>
)}
</AnimatePresence>
);
}
10) Composition of time: parallel vs sequence
Parallel (fade + translate at the same time) - faster in feel.
The sequence (container first, then content) is clearer structure, but longer. Apply when it is important to show the hierarchy.
Avoid steps> 60 ms between closely related elements in the same block.
11) Timing and content
Text: do not animate letter/word-by-word in products; it's a marketing technique.
Numbers/counters: step 40-60 ms batchami, no jitter layout (tabular-nums).
Graphics: opening series 180-240 ms, hover-highlight ≤ 120 ms.
12) Accessibility and perceptual error
Focus styles must appear without delay.
Warnings/errors - minimal animation (≤ 120 ms), no shaking if the user is with AT (assistive tech).
Avoid flashes> 3/s and large contrast flickers.
13) The specifics of iGaming
Bid/Buy:- Press ≤ 100 ms; status' busy'immediately; final toast/indicator - no delay.
- UI response timing is more important than confirmation animation: confirmation is short 120-160 ms.
- Start ≤ 200 ms, uniform cycle, braking 300-500 ms; no endless flickers.
- Win-burst ≤ 500 ms, no strobe; the amount text is AAA.
- Updates by batches (250-1000 ms); visual diff ≤ 160 ms; without layout jumps.
- On hover/focus - debunk backlight 80-120 ms so as not to "blink."
14) Anti-patterns
Linear curves for movements (feeling "mechanical").
Duration> 400 ms for simple button states.
Cascade 100 + ms according to a list of dozens of elements (traction).
Shadows/blur on hundreds of elements in the animation.
Inconsistency: same actions with different timings in the same product.
Delayed focus or delay on keyboard activation.
15) QA timing checklist
Consistency
- Timings and curves are taken from tokens, the same for the same actions.
Response
- Press/hover/focus fit into the scale of 80-180 ms.
- The first visual response ≤ 100 ms.
Choreography
- Input and output are symmetrical; output is 15-30% faster than input.
- The cascade does not exceed 8 elements and 40 ms step.
A11y
- 'prefers-reduced-motion' supported; focus without delay.
- No blinks> 3/s.
Performance
- Only 'transform/opacity' is animated; no mass blur/shadows.
16) Documentation in the design system
"Motion Tokens": duration/easing/stagger + application map (button, overlay, tab, list).
"Rhythm & Phasing": cascade and reversibility schemes.
"Reduce Motion": degradation rules and examples.
"Do/Don't": short clips with timecodes and target metrics (INP/First Feedback).
Brief Summary
Good timing is an instant response, understandable choreography and economical curves. Keep short durations for micro-states, stretch only where it adds meaning, maintain reduce-motion, and don't animate "expensive" properties. Then the interface feels lively and reliable - especially in real-time and high-stakes scenarios.