← Back to Web A11y and Composition Review
SKILL.md
v1.0.0 · 2227 B · text/markdown
--- name: web-a11y-review description: Use when building or reviewing web UI components - an accessibility and composition-pattern checklist covering semantics, focus, forms, motion, and component API design --- # Web A11y & Composition Review Two related concerns that are cheap to get right while writing a component and expensive to retrofit afterward. ## Accessibility checklist - **Semantic HTML first.** Reach for `<button>`, `<nav>`, `<label>` before a `<div>` with an `onClick` and ARIA bolted on. - **Every interactive element is keyboard-operable** — tab order makes sense, focus is visible, Escape closes overlays, Enter/Space activate custom controls built on non-native elements. - **Forms**: every input has a real associated `<label>`, error messages are programmatically associated with their field (not just colored red), required fields are marked in a way a screen reader announces. - **Motion respects `prefers-reduced-motion`** — animations should degrade to an instant state change, not just play anyway. - **Images and icons**: meaningful images get real alt text; decorative ones get empty alt text (`alt=""`), not omitted alt attributes. - **Color is never the only signal** — pair it with an icon, label, or pattern for anything that conveys state (error, success, selected). ## Composition patterns - **Compound components over boolean-prop bloat.** A component accumulating `variant`, `size`, `isX`, `hasY`, `showZ` props is usually better expressed as composable sub-components sharing context (e.g. `<Card><Card.Header/><Card.Body/></Card>` instead of a dozen booleans). - **Lift state to decouple, not to centralize for its own sake.** State belongs at the lowest common ancestor of the components that need it — no higher. - **Explicit variant components beat prop combinations** when the combinations aren't actually independent (a `<PrimaryButton>` and `<DestructiveButton>` can be clearer than `variant="primary"` vs. `variant="destructive"` if their internals diverge meaningfully). ## When to run this During component review, before merging new interactive UI — not as a one-time audit disconnected from the code that's actually shipping.