The Ten Non-Negotiable Standards for Reviewing Animations in UI Development
The ten non-negotiable standards for reviewing animations are strict craft-level rules defined in the emilkowalski/skills repository that enforce purpose-driven motion, performance optimization, and accessibility compliance in UI code reviews.
These standards govern how animation code is evaluated in the emilkowalski/skills repository, acting as hard rules where any violation constitutes a review finding. According to skills/review-animations/SKILL.md (lines 19-42), every animation diff must pass ten specific criteria covering timing, easing, physical correctness, and user accessibility.
Standard 1: Justified Motion
Every animation must serve a clear purpose—spatial consistency, state indication, feedback, explanation, or preventing jarring changes. "It looks cool" is not sufficient justification for frequently-seen UI elements.
- Violation:
/* animation just for flair */withtransition: all 300ms; - Correct:
transition: opacity 150ms ease-out; /* indicates loading */
Standard 2: Frequency-Appropriate Animation
Motion intensity must match usage frequency. Keyboard-initiated actions used 100+ times daily receive no animation; actions performed tens of times daily get reduced motion; occasional actions use standard timing; rare or first-time interactions may include delight-driven animation.
- Violation: Adding
transition: transform 200ms;to keyboard shortcuts - Correct: No transition for shortcuts; subtle opacity shifts only for occasional modals
Standard 3: Responsive Easing
Use ease-out or strong custom cubic-bezier curves for entering and exiting UI. Never use ease-in on UI elements because it delays the moment users see the result. Built-in CSS easings are considered too weak for production interfaces.
- Violation:
transition: all 300ms ease-in; - Correct:
transition: transform 200ms var(--ease-out);(custom curves defined inSTANDARDS.mdlines 31-35)
Standard 4: Sub-300ms UI
All UI animations must complete in under 300 milliseconds. Anything longer requires explicit justification or is reported as a performance finding.
- Violation:
transition: opacity 450ms; - Correct:
transition: opacity 150ms;
Standard 5: Origin and Physical Correctness
Popovers, dropdowns, and tooltips must scale from their trigger point using transform-origin, never from the center. Never animate from scale(0); instead, start from scale(0.9-0.97) combined with opacity fades. Modals are exempt from origin rules (centered scaling is permitted).
- Violation:
transform: scale(0); - Correct:
transform: scale(0.95); opacity: 0;withtransform-origin: var(--transform-origin);
Standard 6: Interruptibility
Rapidly-triggered or gesture-driven motion (toasts, toggles, drags) must be interruptible. Use CSS transitions or springs that can retarget dynamically, avoiding keyframe animations that restart from zero when interrupted.
- Violation:
@keyframes slideIn { … }on frequently appearing toasts - Correct:
transition: transform 300ms ease-out;
Standard 7: GPU-Only Properties
Only animate transform and opacity. Animating layout-affecting properties (width, height, margin, padding, top, left) or using Framer Motion shorthands (x, y, scale) under load triggers performance findings.
- Violation:
transition: width 200ms; - Correct:
transition: transform 200ms;
Standard 8: Accessibility
Motion must honor prefers-reduced-motion (providing gentler motion, not zero animation) and gate hover animations behind @media (hover: hover) and (pointer: fine) to prevent touch device issues.
/* Correct implementation */
@media (prefers-reduced-motion: reduce) {
.elem { transition: none; }
}
@media (hover: hover) and (pointer: fine) {
.elem:hover { transform: scale(1.05); }
}
Standard 9: Asymmetric Enter/Exit
Deliberate user actions (press, hold, confirm) animate slower, while system responses snap fast. Symmetric timing on press-and-release interactions violates this standard.
- Violation:
transition: all 400ms ease;for both press and release - Correct:
- Press:
transition: transform 300ms ease-out; - Release:
transition: transform 100ms linear;
- Press:
Standard 10: Cohesion
Motion must match the component's personality and overall product feel. Playful components may use bouncier springs, while professional dashboards remain crisp. Mismatched personality or jarring cross-fades constitute findings.
- Violation: Overly bouncy spring animations on data-grid column toggles
- Correct: Subtle cubic-bezier curves aligned with UI tone (see
STANDARDS.mdlines 18-26)
Implementation Examples
Here are practical CSS snippets demonstrating correct patterns from the emilkowalski/skills source:
/* ✅ Standard-appropriate easing & duration (Standards 3 & 4) */
button {
transition: background-color 120ms var(--ease-out),
transform 180ms var(--ease-out);
}
/* ❌ Violates Standard 3 (ease-in) and Standard 7 (width) */
button {
transition: width 300ms ease-in;
}
/* ✅ Frequency-appropriate – no animation for keyboard shortcuts (Standard 2) */
.shortcut {
/* No transition – instant feedback */
}
/* ✅ Physical correctness – popover origin (Standard 5) */
.popover {
transform-origin: var(--transform-origin);
}
/* ✅ Interruptible toast (Standard 6) */
.toast {
transition: opacity 250ms ease, transform 250ms ease;
}
/* ✅ GPU-only properties (Standard 7) */
.avatar {
transform: translateX(10px);
opacity: 0.9;
}
/* ✅ Accessibility – reduced-motion handling (Standard 8) */
@media (prefers-reduced-motion: reduce) {
.fade-in {
transition: opacity 80ms linear;
}
}
/* ✅ Asymmetric timing (Standard 9) */
.button:active {
transition: transform 300ms ease-out;
}
.button {
transition: transform 100ms linear;
}
Key Files and Resources
The animation review methodology relies on two authoritative files:
skills/review-animations/SKILL.md: Defines the ten non-negotiable standards, escalation triggers, and output formats (lines 19-42)skills/review-animations/STANDARDS.md: Contains concrete numeric values for easing curves, duration tables, and spring configurations
Summary
- Justified motion: Every animation needs purpose beyond aesthetics
- Frequency-appropriate: Match intensity to daily usage counts (100+/day = no animation)
- Responsive easing: Use
ease-outor custom cubic-bezier; banease-inon UI - Sub-300ms: Hard ceiling on UI animation duration
- Physical correctness: Scale from trigger origin, never from zero
- Interruptibility: Prefer transitions over keyframes for repeated triggers
- GPU-only: Animate
transformandopacityexclusively - Accessibility: Respect
prefers-reduced-motionand pointer media queries - Asymmetric timing: Slower on deliberate actions, faster on system responses
- Cohesion: Align motion personality with component context
Frequently Asked Questions
What happens if an animation violates one of the ten standards?
Any violation is reported as a finding during code review. These are non-negotiable standards, meaning they act as hard rules rather than suggestions, and code cannot merge until issues are resolved or explicitly escalated according to the review protocol in SKILL.md.
Where are the exact easing curve values and duration tables defined?
The specific numeric values for cubic-bezier curves, spring configurations, and duration recommendations are maintained in skills/review-animations/STANDARDS.md, which serves as the concrete reference for the abstract rules defined in the main skill file.
Why does Standard 2 recommend no animation for keyboard shortcuts?
Keyboard-initiated actions occurring 100+ times daily must provide instant feedback to maintain workflow velocity. Animation introduces latency that compounds over hundreds of daily interactions, creating perceived performance degradation and user frustration.
How should I handle reduced motion preferences according to Standard 8?
Implement gentle transitions rather than removing motion entirely. Use prefers-reduced-motion: reduce to provide subtler, faster, or simplified animations that still communicate state changes without triggering vestibular disorders or cognitive load.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →