"Garde-fou accessibilité pour le code UI. Activer quand Claude écrit ou modifie : du HTML/JSX/TSX/Vue/Svelte, des composants interactifs (boutons, formulaires, modals, menus, tabs, accordéons), de la navigation/routing, des images/icônes/médias, ou de la gestion du focus. Couvre WCAG AA : sémantique, labels, clavier, contrastes, touch targets, ARIA. Complémentaire avec frontend-design (qui couvre l'esthétique). Ne pas activer pour du CSS pur sans markup, du JavaScript sans manipulation du DOM, du code backend, ou des fichiers de configuration."
Install
npx skillscat add vendeesign/codebloom/accessibility Install via the SkillsCat registry.
Accessibility — Garde-fou UI
Ce skill s'active quand du code UI est écrit ou modifié, pour garantir l'accessibilité dès la première ligne.
Consulter DESIGN_SYSTEM.md s'il existe — les tokens de couleur et spacing du projet servent de référence pour les contrastes et touch targets.
Zones de déclenchement
- HTML, JSX, TSX, Vue templates, Svelte
- Composants UI (boutons, formulaires, modals, menus, tabs)
- Navigation et routing
- Images, icônes, médias
- Gestion du focus et interactions clavier
Règles fondamentales
HTML sémantique d'abord
| Au lieu de... | Utiliser... |
|---|---|
<div onClick> |
<button> |
<div class="header"> |
<header> |
<span class="link"> |
<a href> |
<div class="list"> |
<ul> / <ol> |
<div class="input"> |
<input> / <select> / <textarea> |
Le HTML sémantique fournit l'accessibilité gratuitement — les lecteurs d'écran, le clavier et les moteurs de recherche comprennent nativement <button>, <nav>, <main>. ARIA est un correctif pour les cas où le HTML natif ne suffit pas, pas un remplacement.
Images et médias
- Toute
<img>a unalt— descriptif si informatif, vide (alt="") si décoratif - Icônes interactives :
aria-labelsur le bouton parent,aria-hidden="true"sur l'icône - Vidéos : sous-titres ou transcription
Formulaires
- Chaque input a un
<label>associé (viahtmlFor/forou wrapping) - Messages d'erreur liés via
aria-describedby - Groupes de champs dans
<fieldset>avec<legend> - Attributs
required,type,inputmode,autocompleteappropriés - Ordre logique des champs (pas de tabindex positif)
Navigation clavier
- Tout ce qui est cliquable est focusable — éléments natifs (
button,a) outabindex="0". Un élément non focusable est invisible pour les utilisateurs clavier - Ordre de focus logique — suit le flux visuel. Un tab order incohérent désoriente l'utilisateur
- Focus visible — supprimer
outlinesans alternative rend la navigation clavier aveugle - Piège de focus dans les modals — sans trap, le focus se perd dans le contenu derrière le modal
Escapeferme les modals, menus, popovers — convention universelle attendue par tous les utilisateurs
Contrastes
- Texte normal : ratio 4.5:1 minimum (WCAG AA)
- Grand texte (>18px bold ou >24px) : ratio 3:1 minimum
- Éléments interactifs : ratio 3:1 pour les bordures et indicateurs
- Ne pas communiquer l'information par la couleur seule (ajouter icône, texte, pattern)
Touch targets
- Taille minimale : 44x44px (WCAG) / 48x48px (Material recommandation)
- Espacement suffisant entre les cibles tactiles
- Zone de tap peut être plus grande que l'élément visuel (padding)
ARIA — Seulement quand nécessaire
<!-- Bon : HTML sémantique suffit -->
<button>Fermer</button>
<!-- Bon : ARIA nécessaire pour un composant custom -->
<div role="tablist">
<button role="tab" aria-selected="true">Onglet 1</button>
<button role="tab" aria-selected="false">Onglet 2</button>
</div>
<div role="tabpanel">Contenu</div>
<!-- Mauvais : ARIA redondant -->
<button role="button">Fermer</button>
<!-- Mauvais : ARIA à la place du sémantique -->
<div role="button" tabindex="0">Fermer</div>Composants courants
| Composant | Points clés |
|---|---|
| Modal | role="dialog", aria-modal="true", aria-labelledby, trap focus, Escape ferme |
| Menu dropdown | role="menu", aria-expanded, flèches pour naviguer, Escape ferme |
| Tabs | role="tablist/tab/tabpanel", aria-selected, flèches pour changer |
| Toast/notification | role="alert" ou aria-live="polite" |
| Accordion | <details>/<summary> natif ou aria-expanded |
| Carrousel | aria-roledescription, aria-label, contrôles pause/play |
Animations
- Respecter
prefers-reduced-motion— réduire ou supprimer les animations - Pas de contenu clignotant (>3 flashes/seconde)
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.01ms !important; }
}Vérification
Outils automatiques
- Linting :
eslint-plugin-jsx-a11y(React),vue-a11y(Vue) — à suggérer lors du/codebloom:setupsi projet UI - Audit :
axe-core/@axe-core/react, Lighthouse accessibility audit - CI :
pa11youaxe-core/clipour tests d'accessibilité automatisés
Vérification manuelle rapide
- Naviguer au clavier seul (Tab, Enter, Escape, flèches)
- Zoomer à 200% — le contenu reste lisible et utilisable ?
- Tester avec un lecteur d'écran (VoiceOver macOS, NVDA Windows)
Comportement
- Signaler les manquements d'accessibilité comme des bugs, pas des suggestions
- Proposer le fix avec le code corrigé
- HTML sémantique avant ARIA — toujours
- Ne pas sur-compliquer — l'accessibilité de base (sémantique, labels, contrastes, clavier) couvre 90% des cas