Développer un composant accessible pour afficher/masquer une zone
Attention ! Cet article a été écrit en 2019. Son contenu a peut-être besoin d’une mise à jour. Complétez votre veille avec des articles plus récents, par exemple en consultant les nouveautés de notre blog accessibilité numérique, ou en lançant une recherche pour trouver des articles similaires, mais à jour.
Lorsque l’on a besoin de réduire des portions de contenus dans une page, notamment pour diminuer la charge informationnelle de contenus annexes, la solution la plus courante est d’utiliser une zone que l’utilisateur peut afficher ou masquer à volonté.
Nous détaillons dans cet article trois méthodes pour gérer ce système de zones affichées/masquées de manière accessible :
- le changement d’intitulé de bouton ;
- l’utilisation du motif de conception
disclosure
; - l’utilisation de l’élément HTML
details
.
Nous vous proposons à la fin de l’article un mémo qui récapitule succinctement les conditions suffisantes à respecter pour choisir ou créer un tel composant accessible.
Technique 1 : modifier l’intitulé du bouton
Il s’agit de la technique la plus ancienne et la plus rudimentaire. L’implémentation consiste à simplement modifier l’intitulé du bouton « Afficher le contenu » par « Masquer le contenu ». Il s’agit d’informer textuellement l’utilisateur du changement d’état.
Vous trouverez dans notre page de test un exemple de code et de fonctionnement de cette technique.
L’élément qui gère l’affichage doit être un élément button
ou implémenter le motif ARIA button
.
Bien que cette technique soit conforme au RGAA (Référentiel Général d’Accessibilité pour les Administrations), l’expérience utilisateur peut être améliorée (et standardisée) en utilisant le motif de conception ARIA disclosure.
Technique 2 : motif ARIA disclosure
Le motif de conception Disclosure décrit les propriétés ARIA et comportements claviers à implémenter pour gérer ce type de composants. À la différence de la première technique que nous venons de décrire, l’intitulé doit ici être neutre puisque l’état ouvert/fermé sera retranscrit par une propriété ARIA.
Vous trouverez dans notre page de test un exemple de code et de fonctionnement du motif ARIA disclosure.
Concernant les propriétés :
- la zone possède un identifiant
id
unique (optionnel) ; - l’élément qui gère l’affichage est un élément
button
ou implémente le motif ARIAbutton
; - l’élément qui gère l’affichage possède la propriété
aria-expanded
:- dont la valeur est
false
lorsque la zone est masquée ; - dont la valeur est
true
lorsque la zone est affichée.
- dont la valeur est
- le bouton possède la propriété
aria-controls
qui référence la valeur de l’identifiant de la zone (optionnel) ;
Au clavier, les touches Entrée et Espace doivent permettre d’activer le bouton, c’est-à-dire successivement afficher et masquer le contenu.
Technique 3 : élément HTML natif details
L’élément HTML5 details
permet de gérer automatiquement des zones affichées/masquées. Ce composant natif permet de délaisser toute la gestion des changements d’état (ouvert/fermé) au navigateur, ce qui réduit d’autant plus les erreurs d’implémentation.
Vous trouverez dans notre page de test un exemple de code et de fonctionnement de l’élément details
.
Le composant est constitué de deux éléments :
- le conteneur, élément
details
, qui contient le bouton, est le contenu à afficher/masquer ; - le bouton, élément
summary
.
details
est fourni avec des goodies :
- un attribut
open
est inséré sur la balisedetails
lorsque le contenu est ouvert ; details
prend en charge l’événement JavaScripttoggle
;- il est possible de styliser le chevron (et donc le supprimer) en ciblant le pseudo-élément
::after
de l’élémentsummary
.
Bien qu’il ne soit pas encore supporté par tous les navigateurs [1], l’élément details
est très bien restitué dans les environnements où il est pris en charge (et donc avec la base de référence du RGAA 3) : sur Firefox et Chrome, avec NVDA ou JAWS, les interactions claviers sont conformes et les restitutions de l’état et du nom du bouton sont cohérentes (« bouton réduit », « bouton développé »).
Quant aux navigateurs qui ne le supportent pas (Internet Explorer et Edge), cela ne pose pas de problème d’accessibilité particulier puisque tout le contenu de l’élément est alors affiché, l’utilisateur accède donc à tout le contenu.
L’utilisation de details
est donc une implémentation conforme au RGAA 3.
Enfin, la principale différence avec le motif disclosure est la construction du code source. En effet, avec details
, le bouton (élément summary
) et la zone masquée/affichée doivent être obligatoirement contenus dans un même élément (details
). De plus, le bouton doit obligatoirement être situé avant la zone gérée, c’est-à-dire que summary
est toujours le premier enfant de details
.
En revanche, avec le motif ARIA disclosure, la construction du code est totalement libre à partir du moment où l’ordre de lecture et de tabulation est respecté.
Ordre de lecture cohérent
Quelle que soit l’implémentation choisie, il faut s’assurer que l’ordre dans lequel une personne ayant recours à une technologie d’assistance lit les contenus est cohérent, c’est-à-dire que lorsque le contenu masqué devient visible, la technologie d’assistance atteint la zone affichée immédiatement après le bouton.
Vous devez également vous assurer que l’ordre de tabulation est cohérent, c’est-à-dire que lorsque le contenu masqué devient visible, la tabulation suivante doit se faire sur le premier élément interactif (lien, bouton, vidéo, champ de formulaire, etc.) de la zone affichée.
Le meilleur moyen de garantir cette cohérence est de faire se succéder les deux éléments (le bouton et la zone) dans le code source.
Cependant, si cela n’est pas possible, il est tout à fait envisageable que le bouton et la zone ne se succèdent pas dans le code, à condition que la reprise de focus soit gérée de manière cohérente par le script.
C’est d’ailleurs la fonction première de la propriété aria-controls
: identifier la zone gérée par le bouton, notamment dans les cas où le lien entre le bouton et la zone ne peut être déduit de manière intuitive (par exemple lorsque la zone gérée n’est pas un nœud frère direct du bouton).
Dans le meilleur des mondes, lorsque l’attribut aria-controls
est présent sur un élément, les technologies d’assistance devraient permettre aux utilisateurs d’accéder directement à la zone identifiée. C’est déjà le cas avec JAWS, qui annonce un raccourci clavier à activer pour atteindre cette zone. Mais à l’heure actuelle, c’est le seul lecteur d’écran à proposer cette fonctionnalité.
Le contenu masqué doit être vraiment masqué !
Sauf cas très particuliers de conception, lorsque le contenu est visuellement masqué, il ne doit être accessible ni aux utilisateurs ni aux technologies d’assistance. Autrement dit, on ne doit pas pouvoir atteindre le contenu masqué avec un lecteur d’écran ni avec la tabulation.
En effet, les zones affichées/masquées permettent d’alléger la page et de réduire la charge cognitive de l’utilisateur. Il faut donc que tous les utilisateurs, quelles que soient leurs technologies d’assistance éventuelles, puissent en bénéficier.
Masquer avec CSS
La méthode la plus robuste pour masquer un contenu est d’utiliser la propriété CSS display:none
. Ainsi, le contenu est non seulement masqué visuellement, mais il est également rendu indisponible pour les technologies d’assistance.
Mais certaines interfaces ne peuvent pas utiliser cette méthode, par exemple lorsqu’il faut gérer des effets d’animations sur ces zones (effet d’agrandissement par exemple).
Dans ces cas, il est possible d’utiliser la propriété visibility:hidden
qui rend le contenu inaccessible, mais permet les effets de transition.
Dans d’autres configurations de transitions encore plus complexes, il est également possible de jouer sur les propriétés CSS de dimensionnement (height
ou width
par exemple) pour afficher certaines zones. Sauf que, dans ce cas, le contenu reste accessible aux technologies d’assistance même s’il est masqué visuellement. Il faut donc accompagner le contenu de propriétés HTML pour qu’il soit ignoré par les technologies d’assistance.
Masquer avec HTML
Deux propriétés HTML peuvent être utilisées pour empêcher les technologies d’assistance de restituer les contenus masqués visuellement :
aria-hidden="true"
sur la zone lorsqu’elle est masquée (lorsque la zone est affichée, on la passe àfalse
ou on retire la propriété) ;tabindex="-1"
sur tous les éléments interactifs (liens, boutons, vidéos, etc.) de la zone lorsqu’elle est masquée (lorsque la zone est affichée, soit on supprime la propriété, soit on lui redonne sa valeur initiale) [2].
Cette implémentation est plus délicate, car le rétablissement des propriétés par défaut (notamment pour tabindex) peut vite devenir complexe à gérer et être source d’erreurs.
Mémo pour être conforme
Il y a 4 exigences pour choisir ou implémenter un composant de ce type de manière accessible et conforme au RGAA 3 :
- le changement d’état peut être identifié :
- par le changement d’intitulé (technique 1) ;
- ou par la mise à jour de la propriété
aria-expanded
(technique 2) ;
- l’élément qui gère la visibilité de la zone :
- est un élément
button
, - ou implémente un motif ARIA
button
;
- est un élément
- la zone est rendue indisponible par l’une des méthodes suivantes :
- par la définition de la propriété CSS
display:none
(ouvisibility:hidden
), - ou par l’ajout de la propriété
aria-hidden="true"
et la modification des valeurs detabindex
sur les éléments interactifs ;
- par la définition de la propriété CSS
- l’ordre de lecture est cohérent :
- l’élément qui gère la visibilité et la zone se succèdent dans le code source ;
- ou le script gère manuellement des reprises de focus cohérentes et logiques.
Il vous est également possible d’utiliser directement l’élément details
puisque nous avons vu qu’il est accessible avec les lecteurs d’écran et navigateurs de la base de référence, il n’est simplement pas supporté par Internet Explorer ni Edge.
Références documentaires
Tests RGAA 3 associés
- Critère 7.1 [A] Chaque script est-il, si nécessaire, compatible avec les technologies d’assistance ?
- Critère 12.13 [A] Dans chaque page web, l’ordre de tabulation est-il cohérent ?
Normes internationales
2 commentaires
Les commentaires sont désormais fermés, mais vous pouvez toujours nous contacter pour réagir à cet article !
Développer un composant accessible pour afficher/masquer une zone
Bonjour et merci pour votre message,
L'intérêt d'utiliser la propriété aria-expanded est justement de ne pas toucher à l'intitulé du bouton. Maintenant, selon l'implémentation, il ne sera pas considéré comme non conforme d'avoir un intitulé changeant "afficher le contenu" / "masquer le contenu" ET la propriété aria-expanded.
L'utilisateur comprendra l'action du bouton, c'est juste que le message restitué par un lecteur d'écran pourra paraître un peu confus.
Par exemple, un bouton qui est déplié et donc le texte est modifié pour décrire l'action à venir, sera restitué : "masquer le contenu développé".
Pour le reste (button avec le role=button, aria-hidden avec visibiliyt:hidden) je n'ai pas de commentaires, il n'y a aucune contrainte à les cumuler.
En espérant avoir répondu à vos interrogations :-)
Développer un composant accessible pour afficher/masquer une zone
Bonjour, super article merci!
Je me pause une petite question, est ce une mauvaise pratique de cumuler les techniques ?
Par exemples :
- Changement d'intitulé cumulé avec la maj de aria-expanded
- Elément Button avec le role="button"
- Propriété CSS Visibility:hidden + aria-hidden="true"
Merci :-)