picasso-skill 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -65
- package/agents/picasso.md +36 -15
- package/bin/install.mjs +1 -1
- package/package.json +2 -2
- package/references/animation-performance.md +244 -0
- package/references/brand-and-identity.md +136 -0
- package/references/code-typography.md +222 -0
- package/references/dark-mode.md +199 -0
- package/references/i18n-visual-patterns.md +177 -0
- package/references/images-and-media.md +222 -0
- package/references/loading-and-states.md +258 -0
- package/references/micro-interactions.md +291 -0
- package/references/navigation-patterns.md +247 -0
- package/references/tables-and-forms.md +227 -0
- package/skills/picasso/SKILL.md +10 -1
- package/templates/picasso-config.md +53 -0
- package/checklists/pre-ship.md +0 -83
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
|
|
8
|
+
32 reference domains • 40+ commands • 11,000+ lines of actionable design intelligence<br/>
|
|
9
9
|
Every interface looks like a senior design engineer spent days on it.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -36,7 +36,7 @@ Existing design skills are shallow. They tell you to "use good typography" witho
|
|
|
36
36
|
|
|
37
37
|
### Depth That No Other Skill Matches
|
|
38
38
|
|
|
39
|
-
Picasso covers **
|
|
39
|
+
Picasso covers **32 specialized reference domains**, each with concrete rules, specific values, and ready-to-use code. This isn't a collection of vague principles -- it's an engineering specification for beautiful interfaces.
|
|
40
40
|
|
|
41
41
|
| Domain | What You Get |
|
|
42
42
|
|---|---|
|
|
@@ -61,6 +61,16 @@ Picasso covers **20 specialized reference domains**, each with concrete rules, s
|
|
|
61
61
|
| **UX Writing** | Error message formula (what + why + fix), button label rules (verb + object), translation expansion percentages, terminology consistency |
|
|
62
62
|
| **Style Presets** | 22 curated visual presets with hex values, font pairings, border-radius, and signature UI elements, mapped to moods |
|
|
63
63
|
| **Performance Optimization** | Vercel's 45 React/Next.js rules across 7 priority tiers with BAD/GOOD code examples |
|
|
64
|
+
| **Navigation Patterns** | Breadcrumbs with ARIA, sidebar collapse, tabs vs button groups, mobile bottom bar vs hamburger, sticky headers, mega menus, skip links |
|
|
65
|
+
| **Tables & Forms** | Sortable tables with `aria-sort`, responsive strategies, inline editing, multi-select, form validation (blur/submit/real-time), multi-step forms |
|
|
66
|
+
| **Loading & States** | Duration rules (<1s/1-3s/3s+/10s+), skeleton shimmer CSS, 5 empty state types, error boundaries, retry with backoff, offline detection |
|
|
67
|
+
| **Dark Mode** | Preference hierarchy, surface elevation (lighter = higher), mode transitions, accent adjustment, image dimming, forced-colors, autofill fix |
|
|
68
|
+
| **Images & Media** | AVIF/WebP/SVG decision tree, srcset/sizes, CLS prevention, favicon multi-format, OG images (1200x630), video backgrounds |
|
|
69
|
+
| **Micro-Interactions** | IntersectionObserver scroll animations, View Transitions API, magnetic cursors, gesture detection (swipe/pinch), animation budget (max 3 concurrent) |
|
|
70
|
+
| **i18n Visual Patterns** | Logical properties for RTL, text expansion by language (+35% German), CJK rendering, Noto font stacks, icon mirroring rules |
|
|
71
|
+
| **Brand & Identity** | Logo sizing (min 24px), clear space rules, lockup variants, 60-30-10 brand color usage, when to bend brand rules |
|
|
72
|
+
| **Animation Performance** | Compositor-only properties (transform + opacity only), will-change lifecycle, layout thrashing batching, `contain` property, GPU hints |
|
|
73
|
+
| **Code Typography** | JetBrains Mono/Fira Code selection, syntax highlighting contrast (3:1 min), code block design, copy button UX, diff views, terminal styling |
|
|
64
74
|
|
|
65
75
|
### The AI-Slop Firewall
|
|
66
76
|
|
|
@@ -272,10 +282,10 @@ We compared Picasso against every publicly available AI design skill as of April
|
|
|
272
282
|
|
|
273
283
|
| Metric | Picasso | Anthropic frontend-design | Impeccable | Taste Skill | Generic skills |
|
|
274
284
|
|---|---|---|---|---|---|
|
|
275
|
-
| **Reference domains** | **
|
|
276
|
-
| **Total lines of guidance** | **
|
|
285
|
+
| **Reference domains** | **32** | 1 | 7 | 1 | 1-3 |
|
|
286
|
+
| **Total lines of guidance** | **11,000+** | ~120 | ~2,500 | ~200 | 50-300 |
|
|
277
287
|
| **Anti-pattern rules** | **50+** | ~10 | ~30 | ~5 | 0-5 |
|
|
278
|
-
| **Steering commands** | **
|
|
288
|
+
| **Steering commands** | **40+** | 0 | 20 | 0 | 0-3 |
|
|
279
289
|
| **ARIA patterns documented** | **12 widgets** | 0 | 0 | 0 | 0 |
|
|
280
290
|
| **React performance rules** | **45 (Vercel)** | 0 | 0 | 0 | 0 |
|
|
281
291
|
| **Chart/data viz guidance** | **Full matrix** | None | None | None | None |
|
|
@@ -336,6 +346,12 @@ npx picasso-skill --cursor
|
|
|
336
346
|
# Install for Codex
|
|
337
347
|
npx picasso-skill --codex
|
|
338
348
|
|
|
349
|
+
# Install for OpenClaw
|
|
350
|
+
npx picasso-skill --openclaw
|
|
351
|
+
|
|
352
|
+
# Or via ClawHub marketplace
|
|
353
|
+
clawhub install picasso
|
|
354
|
+
|
|
339
355
|
# Custom path
|
|
340
356
|
npx picasso-skill --path ./my-skills
|
|
341
357
|
```
|
|
@@ -378,14 +394,15 @@ Picasso ships as both a **skill** (knowledge base) and an **agent** (autonomous
|
|
|
378
394
|
|
|
379
395
|
| | Skill | Agent |
|
|
380
396
|
|---|---|---|
|
|
381
|
-
| **What it is** |
|
|
397
|
+
| **What it is** | 32 reference files of design intelligence | Autonomous design auditor with anti-slop gate |
|
|
382
398
|
| **How it works** | Loaded into context when designing | Runs as a sub-process with its own tools |
|
|
383
|
-
| **When it runs** | When you ask for design help |
|
|
384
|
-
| **Can audit code** | Only when asked |
|
|
385
|
-
| **Can run axe-core** | No | Yes |
|
|
386
|
-
| **Can screenshot pages** | No | Yes (via Playwright) |
|
|
387
|
-
| **Can auto-fix issues** | No | Yes |
|
|
399
|
+
| **When it runs** | When you ask for design help | On explicit commands (/audit, /roast, /godmode, etc.) |
|
|
400
|
+
| **Can audit code** | Only when asked | Yes, with structured scoring |
|
|
401
|
+
| **Can run axe-core** | No | Yes (via CLI) |
|
|
402
|
+
| **Can screenshot pages** | No | Yes (via Playwright MCP) |
|
|
403
|
+
| **Can auto-fix issues** | No | Yes (with pre-flight git/test checks) |
|
|
388
404
|
| **Can enforce design system** | No | Yes (greps for token violations) |
|
|
405
|
+
| **Enforces anti-slop gate** | Via SKILL.md instructions | Yes, mandatory before any code generation |
|
|
389
406
|
|
|
390
407
|
---
|
|
391
408
|
|
|
@@ -405,8 +422,7 @@ Picasso ships as both a **skill** (knowledge base) and an **agent** (autonomous
|
|
|
405
422
|
| `/polish` | Final pass before shipping: visual alignment, typography refinement, color/contrast, all 8 interaction states, micro-interactions, content/copy, edge cases |
|
|
406
423
|
| `/simplify` | Strip to essence: reduce scope, flatten structure, remove decorations, progressive disclosure, shorter copy, fewer variants |
|
|
407
424
|
| `/normalize` | Realign to design system standards: fix hardcoded colors, inconsistent tokens, broken dark mode, spacing violations |
|
|
408
|
-
| `/
|
|
409
|
-
| `/arrange` | Fix layout: establish spacing system, create visual rhythm, choose right layout tool (Flexbox vs Grid), break card grid monotony |
|
|
425
|
+
| `/harden` | Error handling and edge cases: text overflow, i18n, network errors, empty/loading/error states, browser compat |
|
|
410
426
|
|
|
411
427
|
### Amplification
|
|
412
428
|
|
|
@@ -415,8 +431,6 @@ Picasso ships as both a **skill** (knowledge base) and an **agent** (autonomous
|
|
|
415
431
|
| `/animate` | Add purposeful motion: page load choreography, micro-interactions, state transitions, scroll effects, loading delight |
|
|
416
432
|
| `/bolder` | Amplify timid designs: extreme type scale (3x-5x), vibrant color, spatial drama, dramatic shadows, custom elements |
|
|
417
433
|
| `/quieter` | Tone down aggressive designs: reduce saturation to 70-85%, soften weights, increase whitespace, shorter animation distances |
|
|
418
|
-
| `/colorize` | Introduce strategic color: semantic states, accent application, tinted backgrounds, data visualization, decorative elements |
|
|
419
|
-
| `/delight` | Add moments of joy: button feedback, loading delight, success celebrations, personality in copy, sound cues, easter eggs |
|
|
420
434
|
|
|
421
435
|
### Aesthetic Presets
|
|
422
436
|
|
|
@@ -436,15 +450,14 @@ Picasso ships as both a **skill** (knowledge base) and an **agent** (autonomous
|
|
|
436
450
|
| `/haptics` | Add mobile haptic feedback using web-haptics (4 presets + custom patterns) |
|
|
437
451
|
| `/redesign` | Full audit + identify problems + fix systematically + re-audit cycle |
|
|
438
452
|
|
|
439
|
-
###
|
|
453
|
+
### Design Debt
|
|
440
454
|
|
|
441
455
|
| Command | What It Does |
|
|
442
456
|
|---|---|
|
|
443
|
-
| `/
|
|
444
|
-
| `/
|
|
445
|
-
| `/
|
|
446
|
-
| `/
|
|
447
|
-
| `/onboard` | Design onboarding: signup friction reduction, first-run experience, progressive feature discovery, setup checklists |
|
|
457
|
+
| `/backlog` | Create persistent design debt backlog with impact-priority scoring in `.picasso-backlog.md` |
|
|
458
|
+
| `/variants` | Generate 2-3 distinct visual directions for A/B comparison with code previews |
|
|
459
|
+
| `/quick-audit` | 5-minute fast audit: 6 binary pass/fail checks (font, color, layout, spacing, a11y, anti-slop) |
|
|
460
|
+
| `/autorefine` | Binary evaluation loop: 6 criteria, mutate one thing at a time, iterate to 95%+ pass rate |
|
|
448
461
|
|
|
449
462
|
### `/godmode` -- The Nuclear Option
|
|
450
463
|
|
|
@@ -465,29 +478,6 @@ GODMODE Complete: 42 → 87 (+45 points), 47 files modified, 23 issues fixed
|
|
|
465
478
|
|
|
466
479
|
---
|
|
467
480
|
|
|
468
|
-
### Creative
|
|
469
|
-
|
|
470
|
-
| Command | What It Does |
|
|
471
|
-
|---|---|
|
|
472
|
-
| `/godmode` | The ultimate command: interview + audit + score + roast + fix everything + before/after report |
|
|
473
|
-
| `/picasso` | Run the design interview -- deep discovery conversation, generates `.picasso.md` config |
|
|
474
|
-
| `/roast` | Brutally honest critique with designer-Twitter energy. Every roast includes the fix. Rated 🔥-🔥🔥🔥🔥🔥. |
|
|
475
|
-
| `/score` | Quantified 0-100 design score with category breakdown (typography, color, spacing, a11y, motion, responsive, perf, anti-slop) |
|
|
476
|
-
| `/steal <url>` | Extract design DNA from any live website into a `.picasso.md` config |
|
|
477
|
-
| `/mood <word>` | Generate complete design system from a single evocative word (cyberpunk, cottage, luxury, etc.) |
|
|
478
|
-
| `/evolve` | Multi-round iterative refinement: 3 directions → pick → refine → ship |
|
|
479
|
-
| `/compete <url>` | Head-to-head design comparison against a competitor with per-category scoring |
|
|
480
|
-
| `/before-after` | Visual side-by-side comparison report after changes (HTML export) |
|
|
481
|
-
| `/mood-board` | Generate interactive HTML mood board from adjectives |
|
|
482
|
-
| `/design-system-sync` | Detect and auto-fix drift between DESIGN.md and actual code |
|
|
483
|
-
| `/preset <name>` | Apply a curated preset (linear, stripe, vercel, notion, brutalist, etc.) |
|
|
484
|
-
|
|
485
|
-
### Advanced
|
|
486
|
-
|
|
487
|
-
| Command | What It Does |
|
|
488
|
-
|---|---|
|
|
489
|
-
| `/overdrive` | Technically extraordinary effects. View Transitions, scroll-driven animations, WebGL, @property gradients, Web Audio, spring physics. 60fps. Progressive enhancement. |
|
|
490
|
-
|
|
491
481
|
### Automation (Agent-Only)
|
|
492
482
|
|
|
493
483
|
| Command | What It Does |
|
|
@@ -505,27 +495,39 @@ GODMODE Complete: 42 → 87 (+45 points), 47 files modified, 23 issues fixed
|
|
|
505
495
|
## References
|
|
506
496
|
|
|
507
497
|
```
|
|
508
|
-
references/
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
498
|
+
references/ # 32 files, 9,300+ lines
|
|
499
|
+
anti-patterns.md # 50+ banned patterns (THE MOST IMPORTANT FILE)
|
|
500
|
+
typography.md # Type systems, font pairing, scales, OpenType, vertical rhythm
|
|
501
|
+
color-and-contrast.md # OKLCH, tinted neutrals, dark mode, 60-30-10, dangerous combos
|
|
502
|
+
spatial-design.md # 4px spacing scale, grids, hierarchy, Squint Test
|
|
503
|
+
depth-and-elevation.md # Dual shadows, layering, shadow scale, z-index, hover patterns
|
|
504
|
+
motion-and-animation.md # Duration rule, easing curves, staggering, text morphing
|
|
505
|
+
micro-interactions.md # Scroll animations, View Transitions, gestures, magnetic cursors
|
|
506
|
+
animation-performance.md # Compositor-only props, will-change, layout thrashing, contain
|
|
507
|
+
interaction-design.md # 8 states, forms, focus, Popover API, dropdown positioning
|
|
508
|
+
navigation-patterns.md # Breadcrumbs, sidebar, tabs, bottom bar, mega menus, skip links
|
|
509
|
+
tables-and-forms.md # Sortable tables, inline editing, validation, multi-step forms
|
|
510
|
+
loading-and-states.md # Skeletons, error boundaries, 5 empty state types, offline
|
|
511
|
+
responsive-design.md # Input method detection, safe areas, container queries
|
|
512
|
+
dark-mode.md # Preference hierarchy, elevation, transitions, testing
|
|
513
|
+
images-and-media.md # Format selection, srcset, favicons, OG images, video
|
|
514
|
+
brand-and-identity.md # Logo sizing, brand color 60-30-10, lockup variants
|
|
515
|
+
i18n-visual-patterns.md # RTL, logical properties, text expansion, CJK, Noto stacks
|
|
516
|
+
code-typography.md # Monospace fonts, syntax highlighting, code blocks, diff views
|
|
517
|
+
sensory-design.md # soundcn, web-haptics, multi-sensory integration
|
|
518
|
+
react-patterns.md # Server Components, composition, state management, styling
|
|
519
|
+
design-system.md # 9-section DESIGN.md format, theme generation, tokens
|
|
520
|
+
generative-art.md # Philosophy-first process, p5.js, seeded randomness
|
|
521
|
+
component-patterns.md # 40+ components, state matrix, compound patterns
|
|
522
|
+
ux-psychology.md # Gestalt, Fitts's/Hick's/Miller's/Jakob's Law, F/Z-pattern
|
|
523
|
+
ux-writing.md # Error formula, button labels, empty states, terminology
|
|
524
|
+
data-visualization.md # Chart selection matrix, dashboard layouts, Tufte
|
|
525
|
+
conversion-design.md # Landing pages, CTAs, pricing, onboarding, notifications
|
|
526
|
+
accessibility-wcag.md # 12 ARIA patterns, WCAG 2.2, SPA focus, accessible tables
|
|
527
|
+
modern-css-performance.md # Nesting, :has(), @layer, View Transitions, Tailwind v4
|
|
528
|
+
performance-optimization.md # 45 Vercel rules across 7 priority tiers
|
|
529
|
+
style-presets.md # 22 visual presets with OKLCH values and font pairings
|
|
530
|
+
tools-catalog.md # torph, soundcn, Lucide, Facehash, better-icons
|
|
529
531
|
```
|
|
530
532
|
|
|
531
533
|
---
|
package/agents/picasso.md
CHANGED
|
@@ -176,23 +176,44 @@ If 3+ are checked, you MUST change your commitments until fewer than 3 remain.
|
|
|
176
176
|
Your design knowledge comes from the Picasso skill reference files. Before any audit or design work, load the relevant references:
|
|
177
177
|
|
|
178
178
|
```
|
|
179
|
-
skills/picasso/SKILL.md
|
|
180
|
-
skills/picasso/references/anti-patterns.md
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
skills/picasso/references/
|
|
184
|
-
skills/picasso/references/
|
|
185
|
-
skills/picasso/references/
|
|
186
|
-
skills/picasso/references/
|
|
187
|
-
skills/picasso/references/
|
|
188
|
-
skills/picasso/references/
|
|
189
|
-
skills/picasso/references/
|
|
190
|
-
skills/picasso/references/design
|
|
191
|
-
skills/picasso/references/
|
|
192
|
-
skills/picasso/references/
|
|
179
|
+
skills/picasso/SKILL.md # Core rules and workflow (always load)
|
|
180
|
+
skills/picasso/references/anti-patterns.md # What NOT to do (always load)
|
|
181
|
+
|
|
182
|
+
# Load based on what the task involves:
|
|
183
|
+
skills/picasso/references/typography.md # Fonts, scales, pairing
|
|
184
|
+
skills/picasso/references/color-and-contrast.md # OKLCH, tinted neutrals
|
|
185
|
+
skills/picasso/references/spatial-design.md # Spacing, grids, hierarchy
|
|
186
|
+
skills/picasso/references/depth-and-elevation.md # Shadows, z-index, layering
|
|
187
|
+
skills/picasso/references/motion-and-animation.md # Easing, staggering, duration
|
|
188
|
+
skills/picasso/references/micro-interactions.md # Scroll animations, gestures, View Transitions
|
|
189
|
+
skills/picasso/references/animation-performance.md # Compositor props, will-change, contain
|
|
190
|
+
skills/picasso/references/interaction-design.md # Forms, focus, states, Popover API
|
|
191
|
+
skills/picasso/references/navigation-patterns.md # Breadcrumbs, sidebar, tabs, bottom bar
|
|
192
|
+
skills/picasso/references/tables-and-forms.md # Sortable tables, validation, multi-step
|
|
193
|
+
skills/picasso/references/loading-and-states.md # Skeletons, empty states, error boundaries
|
|
194
|
+
skills/picasso/references/responsive-design.md # Mobile-first, container queries
|
|
195
|
+
skills/picasso/references/dark-mode.md # Preference hierarchy, elevation, testing
|
|
196
|
+
skills/picasso/references/images-and-media.md # Formats, srcset, favicons, OG images
|
|
197
|
+
skills/picasso/references/brand-and-identity.md # Logo sizing, brand color usage
|
|
198
|
+
skills/picasso/references/i18n-visual-patterns.md # RTL, logical properties, CJK
|
|
199
|
+
skills/picasso/references/code-typography.md # Monospace, syntax highlighting, diffs
|
|
200
|
+
skills/picasso/references/sensory-design.md # Sound, haptics
|
|
201
|
+
skills/picasso/references/react-patterns.md # Server Components, Tailwind v4
|
|
202
|
+
skills/picasso/references/accessibility-wcag.md # ARIA, WCAG 2.2, keyboard nav
|
|
203
|
+
skills/picasso/references/design-system.md # DESIGN.md, theming, tokens
|
|
204
|
+
skills/picasso/references/generative-art.md # p5.js, SVG, canvas
|
|
205
|
+
skills/picasso/references/component-patterns.md # Naming, taxonomy, state matrix
|
|
206
|
+
skills/picasso/references/ux-psychology.md # Gestalt, Fitts's Law, heuristics
|
|
207
|
+
skills/picasso/references/ux-writing.md # Error messages, microcopy, CTAs
|
|
208
|
+
skills/picasso/references/data-visualization.md # Chart matrix, dashboards, Tufte
|
|
209
|
+
skills/picasso/references/conversion-design.md # Landing pages, CTAs, pricing
|
|
210
|
+
skills/picasso/references/modern-css-performance.md # Nesting, :has(), @layer, subgrid
|
|
211
|
+
skills/picasso/references/performance-optimization.md # 45 Vercel rules, Core Web Vitals
|
|
212
|
+
skills/picasso/references/style-presets.md # 22 curated presets with values
|
|
213
|
+
skills/picasso/references/tools-catalog.md # torph, soundcn, Lucide, Facehash
|
|
193
214
|
```
|
|
194
215
|
|
|
195
|
-
Find these files by searching
|
|
216
|
+
Find these files by searching `.claude/skills/picasso/`, `~/.claude/skills/picasso/`, or by globbing `**/picasso/SKILL.md`. Load `anti-patterns.md` on every invocation. Load other references based on what you find in the code.
|
|
196
217
|
|
|
197
218
|
## Phase 1: Gather Context
|
|
198
219
|
|
package/bin/install.mjs
CHANGED
|
@@ -29,7 +29,7 @@ if (command === "help" || command === "--help" || command === "-h") {
|
|
|
29
29
|
npx picasso-skill --path DIR Install to a custom directory
|
|
30
30
|
|
|
31
31
|
What gets installed:
|
|
32
|
-
.claude/skills/picasso/ Skill (knowledge base:
|
|
32
|
+
.claude/skills/picasso/ Skill (knowledge base: 32 reference files)
|
|
33
33
|
.claude/agents/picasso.md Agent (autonomous design auditor)
|
|
34
34
|
`);
|
|
35
35
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "picasso-skill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "The ultimate AI design skill for producing distinctive, production-grade frontend interfaces",
|
|
5
5
|
"bin": {
|
|
6
6
|
"picasso-skill": "./bin/install.mjs"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"agents/",
|
|
36
36
|
"commands/",
|
|
37
37
|
"references/",
|
|
38
|
-
"
|
|
38
|
+
"templates/",
|
|
39
39
|
"LICENSE"
|
|
40
40
|
]
|
|
41
41
|
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Animation Performance Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
1. Compositor-Only Properties
|
|
5
|
+
2. Will-Change Best Practices
|
|
6
|
+
3. Layout Thrashing
|
|
7
|
+
4. IntersectionObserver vs Scroll Events
|
|
8
|
+
5. Web Animations API
|
|
9
|
+
6. Performance Measurement
|
|
10
|
+
7. Testing on Low-End Devices
|
|
11
|
+
8. Contain Property
|
|
12
|
+
9. Common Mistakes
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Compositor-Only Properties
|
|
17
|
+
|
|
18
|
+
Only two CSS properties can be animated without triggering layout or paint: **transform** and **opacity**. Everything else causes reflow.
|
|
19
|
+
|
|
20
|
+
| Property | Layout | Paint | Composite | Animate? |
|
|
21
|
+
|---|---|---|---|---|
|
|
22
|
+
| `transform` | No | No | Yes | **Yes** |
|
|
23
|
+
| `opacity` | No | No | Yes | **Yes** |
|
|
24
|
+
| `filter` | No | Yes | Yes | Carefully |
|
|
25
|
+
| `background-color` | No | Yes | No | Avoid |
|
|
26
|
+
| `width`, `height` | Yes | Yes | No | **Never** |
|
|
27
|
+
| `top`, `left` | Yes | Yes | No | **Never** |
|
|
28
|
+
| `margin`, `padding` | Yes | Yes | No | **Never** |
|
|
29
|
+
| `border-radius` | No | Yes | No | Avoid |
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
/* Good: compositor-only */
|
|
33
|
+
.slide-in {
|
|
34
|
+
transform: translateX(-100%);
|
|
35
|
+
opacity: 0;
|
|
36
|
+
transition: transform 300ms var(--ease-out), opacity 300ms var(--ease-out);
|
|
37
|
+
}
|
|
38
|
+
.slide-in.active {
|
|
39
|
+
transform: translateX(0);
|
|
40
|
+
opacity: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Bad: triggers layout on every frame */
|
|
44
|
+
.slide-in-bad {
|
|
45
|
+
left: -100%;
|
|
46
|
+
transition: left 300ms ease;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. Will-Change Best Practices
|
|
53
|
+
|
|
54
|
+
`will-change` promotes an element to its own compositor layer. This speeds up animation but consumes GPU memory.
|
|
55
|
+
|
|
56
|
+
Rules:
|
|
57
|
+
- Add `will-change` BEFORE the animation starts (e.g., on hover, not in the animation itself).
|
|
58
|
+
- Remove it AFTER the animation completes.
|
|
59
|
+
- Never use `will-change: all` — it promotes everything.
|
|
60
|
+
- Never apply it to more than 10 elements simultaneously.
|
|
61
|
+
- Don't put it in your stylesheet permanently.
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
// Good: apply before, remove after
|
|
65
|
+
element.addEventListener('mouseenter', () => {
|
|
66
|
+
element.style.willChange = 'transform';
|
|
67
|
+
});
|
|
68
|
+
element.addEventListener('transitionend', () => {
|
|
69
|
+
element.style.willChange = 'auto';
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
/* Acceptable: for elements that are ALWAYS animated (e.g., loading spinners) */
|
|
75
|
+
.spinner { will-change: transform; }
|
|
76
|
+
|
|
77
|
+
/* Bad: permanent will-change on static elements */
|
|
78
|
+
.card { will-change: transform, opacity; } /* don't do this */
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 3. Layout Thrashing
|
|
84
|
+
|
|
85
|
+
Reading layout properties then writing them in a loop forces the browser to recalculate layout on every iteration.
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
// BAD: layout thrashing (read-write-read-write)
|
|
89
|
+
elements.forEach(el => {
|
|
90
|
+
const height = el.offsetHeight; // READ — forces layout
|
|
91
|
+
el.style.height = height + 10 + 'px'; // WRITE — invalidates layout
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// GOOD: batch reads, then batch writes
|
|
95
|
+
const heights = elements.map(el => el.offsetHeight); // all reads first
|
|
96
|
+
elements.forEach((el, i) => {
|
|
97
|
+
el.style.height = heights[i] + 10 + 'px'; // all writes after
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Properties that trigger forced layout when read: `offsetHeight`, `offsetWidth`, `getBoundingClientRect()`, `scrollTop`, `clientHeight`, `getComputedStyle()`.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 4. IntersectionObserver vs Scroll Events
|
|
106
|
+
|
|
107
|
+
| | `scroll` event | IntersectionObserver |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| Performance | Fires every pixel, blocks main thread | Async, fires on threshold crossing |
|
|
110
|
+
| Throttling | Manual (requestAnimationFrame) | Built-in |
|
|
111
|
+
| Use case | Scroll-linked animation (position) | Visibility detection (enter/exit) |
|
|
112
|
+
| Recommendation | Almost never | Almost always |
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
// Good: IntersectionObserver for reveal animations
|
|
116
|
+
const observer = new IntersectionObserver(
|
|
117
|
+
(entries) => {
|
|
118
|
+
entries.forEach(entry => {
|
|
119
|
+
entry.target.classList.toggle('visible', entry.isIntersecting);
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
{ threshold: 0.1 }
|
|
123
|
+
);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For scroll-linked animations where you need exact scroll position, use the Scroll-Driven Animations API:
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
@keyframes fade-in {
|
|
130
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
131
|
+
to { opacity: 1; transform: translateY(0); }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.scroll-reveal {
|
|
135
|
+
animation: fade-in linear;
|
|
136
|
+
animation-timeline: view();
|
|
137
|
+
animation-range: entry 0% entry 100%;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 5. Web Animations API
|
|
144
|
+
|
|
145
|
+
For complex JS-driven animations, use WAAPI instead of manual `requestAnimationFrame`:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
element.animate(
|
|
149
|
+
[
|
|
150
|
+
{ transform: 'translateY(20px)', opacity: 0 },
|
|
151
|
+
{ transform: 'translateY(0)', opacity: 1 }
|
|
152
|
+
],
|
|
153
|
+
{
|
|
154
|
+
duration: 300,
|
|
155
|
+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
|
|
156
|
+
fill: 'forwards'
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Benefits over CSS: programmable, cancellable, can read progress, can reverse.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 6. Performance Measurement
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
// Measure animation frame rate
|
|
169
|
+
let frames = 0;
|
|
170
|
+
let lastTime = performance.now();
|
|
171
|
+
|
|
172
|
+
function countFrames() {
|
|
173
|
+
frames++;
|
|
174
|
+
const now = performance.now();
|
|
175
|
+
if (now - lastTime >= 1000) {
|
|
176
|
+
console.log(`FPS: ${frames}`);
|
|
177
|
+
frames = 0;
|
|
178
|
+
lastTime = now;
|
|
179
|
+
}
|
|
180
|
+
requestAnimationFrame(countFrames);
|
|
181
|
+
}
|
|
182
|
+
requestAnimationFrame(countFrames);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Chrome DevTools:
|
|
186
|
+
1. Performance tab → Record → interact with animations → Stop
|
|
187
|
+
2. Look for long frames (> 16ms) in the flame chart
|
|
188
|
+
3. Rendering tab → Paint flashing (green = repaint, should be minimal)
|
|
189
|
+
4. Rendering tab → Layer borders (orange = composited layers)
|
|
190
|
+
|
|
191
|
+
Target: 60fps = 16.67ms per frame. If ANY frame takes > 33ms, users perceive jank.
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 7. Testing on Low-End Devices
|
|
196
|
+
|
|
197
|
+
Your M-series Mac is not representative. Test with:
|
|
198
|
+
- **Chrome DevTools CPU throttling:** Performance tab → CPU → 6x slowdown
|
|
199
|
+
- **Network throttling:** Slow 3G preset to test loading animations
|
|
200
|
+
- **Real device:** Test on a 3-year-old Android phone if possible
|
|
201
|
+
|
|
202
|
+
If an animation stutters at 6x CPU throttle, reduce:
|
|
203
|
+
1. Number of concurrent animations
|
|
204
|
+
2. Element count being animated
|
|
205
|
+
3. Complexity of each animation
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 8. Contain Property
|
|
210
|
+
|
|
211
|
+
`contain` tells the browser what NOT to recalculate when an element changes.
|
|
212
|
+
|
|
213
|
+
```css
|
|
214
|
+
/* Isolate layout/paint to this element */
|
|
215
|
+
.card {
|
|
216
|
+
contain: layout paint;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Full isolation — best for off-screen or independent components */
|
|
220
|
+
.widget {
|
|
221
|
+
contain: strict; /* = size + layout + paint + style */
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Content containment — layout + paint + style (most common) */
|
|
225
|
+
.list-item {
|
|
226
|
+
contain: content;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Use `contain: content` on repeated elements (list items, cards) to prevent layout changes from propagating to siblings.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 9. Common Mistakes
|
|
235
|
+
|
|
236
|
+
- **Animating `width`/`height`/`top`/`left`.** Use `transform: translate/scale` instead.
|
|
237
|
+
- **`will-change` on everything.** Max 10 elements. Remove after animation completes.
|
|
238
|
+
- **`addEventListener('scroll')` for visibility.** Use IntersectionObserver.
|
|
239
|
+
- **Reading layout properties in animation loops.** Batch reads before writes.
|
|
240
|
+
- **Testing only on fast hardware.** Use Chrome CPU throttling at 6x.
|
|
241
|
+
- **No frame budget awareness.** 16ms per frame. If your JS takes 20ms, you drop frames.
|
|
242
|
+
- **CSS `transition: all`.** Transitions every property including layout triggers.
|
|
243
|
+
- **Forgetting `contain` on repeated elements.** One card's layout change recalculates the entire list.
|
|
244
|
+
- **`requestAnimationFrame` without cancellation.** Always store the ID and `cancelAnimationFrame` on cleanup.
|