Aller au contenu principal

Accessibilite Vue.js : guide RGAA complet

Guide complet pour rendre vos applications Vue.js accessibles et conformes au RGAA : directives, focus, aria-live, transitions et checklist.

18 min de lectureDebutant a avance

1. Pourquoi l'accessibilité est cruciale en Vue.js

Vue.js est adopté par des millions de développeurs pour sa simplicité et sa réactivité. Mais cette réactivité crée des défis d'accessibilité spécifiques. Le système de templates de Vue génère du HTML dynamiquement, et chaque mise à jour réactive du DOM peut potentiellement briser l'expérience des utilisateurs de technologies d'assistance.

Le système réactif de Vue (ref, reactive, computed) met à jour le DOM automatiquement lorsque les données changent. Mais les lecteurs d'écran ne détectent pas ces changements sauf si le développeur utilise des régions aria-live pour les signaler. Un compteur qui s'incrémente, un message d'erreur qui apparaît, un résultat de recherche qui se met à jour — sans aria-live, ces informations sont invisibles pour une partie de vos utilisateurs.

Le rendu basé sur les templates encourage la création de composants personnalisés qui remplacent les éléments HTML natifs. Un <BaseButton> peut facilement oublier de transmettre les attributs d'accessibilité. Un <CustomSelect> perd les comportements natifs du clavier. C'est une dette d'accessibilité silencieuse.

Avec Vue 3 et la Composition API, la logique d'accessibilité peut désormais être encapsulée dans des composables réutilisables. Un composable useFocusTrap() ou useAnnounce() peut être partagé entre tous vos composants, garantissant une implémentation cohérente. C'est un avantage significatif par rapport à l'Options API où la logique était plus difficile à réutiliser.

En France, le RGAA 4.1.2 impose des obligations légales d'accessibilité. Avec l'European Accessibility Act entrant en vigueur en 2025, le secteur privé est désormais concerné. Maîtriser l'accessibilité dans Vue.js n'est plus une option — c'est une obligation légale et un devoir éthique.

2. Erreurs d'accessibilité courantes en Vue.js

Voici les pièges les plus fréquents dans les applications Vue.js, et pourquoi ils posent problème pour l'accessibilité.

v-html sans sanitisation

La directive v-html injecte du HTML brut dans le DOM. Au-delà du risque XSS, le contenu injecté peut contenir des éléments inaccessibles : images sans alt, liens vides, structures de heading incorrectes. Le compilateur de templates Vue ne vérifie pas l'accessibilité du HTML injecté via v-html, et les linters ne peuvent pas l'analyser statiquement.

Clé manquante sur v-for

Omettre l'attribut :key sur les boucles v-for entraîne des mises à jour DOM incohérentes. Vue réutilise les éléments au lieu de les recréer, ce qui peut déplacer le focus de manière inattendue. Un utilisateur naviguant au clavier dans une liste peut se retrouver sur un élément complètement différent après une mise à jour réactive.

Teleport et gestion du focus

Le composant <Teleport> de Vue 3 déplace un sous-arbre DOM vers un autre emplacement (typiquement body pour les modales). Mais le focus reste à sa position originale. Si vous ouvrez une modale téléportée sans déplacer le focus, l'utilisateur au clavier ne sait pas qu'une modale est apparue et peut interagir avec le contenu en arrière-plan.

Transitions qui brisent les lecteurs d'écran

Les composants <Transition> et <TransitionGroup> de Vue appliquent des classes CSS pendant les animations. Le problème : pendant la phase de transition, les éléments peuvent avoir opacity: 0 ou être en dehors de la zone visible. Les lecteurs d'écran peuvent annoncer un contenu qui n'est pas encore visible, ou ignorer un contenu qui est en train d'apparaître. De plus, les animations rapides ou clignotantes peuvent déclencher des crises chez les personnes épileptiques (critère WCAG 2.3.1).

3. Bonnes pratiques avec exemples de code

Directives custom pour l'accessibilité

Les directives personnalisées de Vue sont idéales pour encapsuler des comportements d'accessibilité réutilisables. Voici deux directives essentielles : v-focus pour le focus automatique et v-announce pour les annonces aux lecteurs d'écran.

Gestion du focus avec template refs et nextTick

En Vue 3, les template refs combinées à nextTick permettent de déplacer le focus de manière fiable après une mise à jour du DOM. C'est indispensable pour les modales, les notifications d'erreur et les changements de contenu dynamique.

Régions aria-live avec données réactives

Le système réactif de Vue est parfait pour alimenter des régions aria-live. Voici un composable réutilisable qui centralise les annonces pour les technologies d'assistance.

Transitions accessibles avec prefers-reduced-motion

Les utilisateurs qui souffrent de troubles vestibulaires ou d'épilepsie peuvent configurer leur système pour réduire les animations. Vue doit respecter ce choix. Voici un composable et son intégration avec le composant <Transition>.

Formulaires accessibles avec v-model et validation

Les formulaires Vue utilisent v-model pour la liaison bidirectionnelle. Pour l'accessibilité, chaque champ doit avoir un label associé, les erreurs doivent être annoncées, et la navigation au clavier doit être fluide.

Navigation et focus avec vue-router

Les Single Page Applications ne rechargent pas la page lors de la navigation. Les lecteurs d'écran ne sont pas informés du changement de page. Il faut manuellement déplacer le focus et annoncer la nouvelle page.

Pensez également à implémenter un lien d'évitement ("Aller au contenu principal") en haut de votre composant App.vue. Ce lien permet aux utilisateurs de clavier et de lecteurs d'écran de sauter la navigation répétitive.

4. Critères RGAA clés pour Vue.js

Le RGAA 4.1.2 contient 106 critères. Voici ceux qui sont le plus directement impactés par le développement Vue.js, avec les points d'attention spécifiques au framework.

Critère 7.1 — Scripts accessibles

Chaque script doit être compatible avec les technologies d'assistance. En Vue.js, cela concerne directement les composants interactifs générés par le framework.

  • Les composants personnalisés (<BaseSelect>, <Modal>, <Tabs>) doivent implémenter les patterns WAI-ARIA correspondants
  • Les @click sur des <div> ou <span> doivent avoir un équivalent clavier (@keydown.enter, @keydown.space) et un rôle
  • Les mises a jour reactives du DOM doivent etre annoncees aux technologies d'assistance via aria-live

Critère 7.3 — Composants interactifs

Les composants interactifs doivent être utilisables au clavier et correctement identifiés par leur rôle ARIA.

  • Chaque composant interactif doit être focusable et opérable au clavier (Enter, Espace, flèches directionnelles)
  • Les <Teleport> pour les modales doivent piéger le focus et le restaurer à la fermeture
  • Les composants de type onglets, accordéons et menus déroulants doivent suivre les patterns WAI-ARIA Authoring Practices

Critère 12.1 — Navigation

Le site doit disposer d'au moins deux systemes de navigation parmi : menu, plan du site, moteur de recherche.

  • Avec vue-router, chaque changement de route doit déplacer le focus et annoncer la nouvelle page
  • Les liens d'évitement doivent être présents et fonctionnels, même dans une SPA
  • La navigation doit être cohérente entre les pages et identifiable par les landmarks ARIA (<nav>, <main>, <header>, <footer>)

Critère 11.1 — Formulaires

Chaque champ de formulaire doit avoir une étiquette associée. Les erreurs doivent être clairement identifiées.

  • Associer chaque <input> avec v-model a un <label> via for/id
  • Utiliser aria-describedby pour lier les messages d'aide et d'erreur aux champs
  • Marquer les champs invalides avec aria-invalid="true" et déplacer le focus vers la première erreur
  • Les composants de formulaire personnalisés doivent transmettre correctement les attributs d'accessibilité via v-bind="$attrs" ou useAttrs()

5. Packages et outils recommandés

Ces outils vous aident à développer, tester et maintenir l'accessibilité de vos applications Vue.js.

vue-axe

Intègre le moteur axe-core directement dans votre application Vue en développement. Affiche les violations d'accessibilité dans la console du navigateur en temps réel, avec des suggestions de correction. Indispensable pour détecter les problèmes tôt dans le cycle de développement.

eslint-plugin-vuejs-accessibility

Plugin ESLint qui analyse statiquement vos templates Vue pour détecter les problèmes d'accessibilité : images sans alt, labels manquants, rôles invalides, éléments non focusables avec gestionnaires de clic. S'intègre dans votre CI/CD pour prévenir les régressions.

Headless UI Vue

Librairie de composants non stylés (headless) développée par l'équipe Tailwind CSS. Fournit des composants complètement accessibles : Dialog, Disclosure, Listbox, Menu, Popover, RadioGroup, Switch, Tabs. Chaque composant implémente le pattern WAI-ARIA correspondant avec gestion complète du clavier et du focus. Vous n'avez qu'à ajouter vos styles.

Radix Vue

Port non officiel de Radix UI pour Vue.js. Offre une collection de composants primitifs accessibles et non stylés : Accordion, AlertDialog, Checkbox, Collapsible, Combobox, ContextMenu, Dialog, DropdownMenu, HoverCard, NavigationMenu, Popover, Progress, RadioGroup, ScrollArea, Select, Separator, Slider, Switch, Tabs, Toast, Toggle, Toolbar, Tooltip. Plus complet que Headless UI, avec un excellent support TypeScript et une API composable.

6. Checklist accessibilité Vue.js

Utilisez cette checklist comme référence rapide lors du développement et de la revue de code de vos applications Vue.js.

Structure et sémantique

    Interactivité et focus

      Contenu dynamique

        Formulaires

          Outillage

            Questions fréquentes

            Vue.js est-il accessible par defaut ?

            Non. Vue.js genere du HTML reactif, mais ne garantit ni la bonne semantique, ni la gestion du focus, ni le respect de prefers-reduced-motion sans implementation explicite.

            Comment gerer le focus apres un changement de route avec vue-router ?

            Utilisez afterEach avec nextTick pour deplacer le focus vers le contenu principal apres chaque navigation.

            Quelle est la difference entre v-show et v-if pour l'accessibilite ?

            v-if retire l'element du DOM, alors que v-show le masque avec display:none. Pour les annonces aria-live, v-if est souvent preferable car l'insertion declenche la lecture.

            Comment rendre les transitions Vue.js accessibles ?

            Respectez prefers-reduced-motion et desactivez ou simplifiez les animations quand l'utilisateur le demande.

            Faut-il utiliser une librairie de composants pour l'accessibilite Vue.js ?

            Oui, quand vous implementez des patterns complexes comme dialog, tabs ou combobox. Radix Vue ou Headless UI Vue limitent les erreurs.

            Comment tester l'accessibilite d'une application Vue.js ?

            Combinez vue-axe, eslint-plugin-vuejs-accessibility, tests clavier et verifications avec un lecteur d'ecran.

            Teleport et accessibilite : quels pieges eviter ?

            Une modale teleporte doit pieger le focus, le restaurer a la fermeture et marquer correctement son role et son contexte modal.

            Vue 3 Composition API change-t-il quelque chose pour l'accessibilite ?

            Pas sur le fond, mais elle facilite la creation de composables reutilisables pour le focus, les annonces live et le clavier.

            Testez l'accessibilite de votre application Vue.js

            RGAA Scanner analyse automatiquement votre site et genere un rapport detaille en quelques secondes pour identifier les non-conformites avant vos utilisateurs.

            Scanner mon site gratuitement