Accessibilité de niveau supérieur : 5 façons dont j'ai rendu le guide freeCodeCamp plus utilisable pour les personnes handicapées
J'ai passé la majorité du Hacktoberfest 2017 à travailler avec des gens formidables chez freeCodeCamp . Mon objectif était spécifiquement d'aider à amener l'accessibilité de leur site Guide au niveau supérieur.
La première fois que j'ai vu le site, je savais que ce serait une ressource fantastique pour beaucoup de gens, alors j'ai relevé le défi de m'assurer que sa convivialité était de premier ordre pour tout le monde !
Travailler sur le site était également très amusant car il est construit avec React , ce qui a apporté quelques défis de codage supplémentaires en cours de route.
Voyons ensemble les 5 problèmes que j'ai trouvés et comment je les ai résolus !
Amélioration de l'accessibilité n° 1 : Ignorer le lien de navigation indisponible
L'une des premières choses que je vérifie sur un site est s'il y a un lien de saut de navigation disponible. Les liens de saut de navigation sont une fonctionnalité petite mais pratique pour tout site à avoir pour les utilisateurs de clavier uniquement ou de lecteur d'écran. Pourquoi?
Le problème
Sans lien de saut de navigation, les personnes utilisant uniquement le clavier pour Tab
devraient parcourir chaque lien de la barre latérale chaque fois que la page se recharge. Comme il y a beaucoup de liens disponibles, naviguer dans cette section serait fastidieux.
La solution
La mise en œuvre d'un lien de saut de navigation est assez simple. C'est généralement le premier élément du DOM (Document Object Model) et au clic, le focus du clavier est envoyé à l'élément de page qui contient le contenu principal de la page.
Le lien que j'ai ajouté a été codé comme suit :
<a className="skip-link sr-only sr-only-focusable" href="#main"> Skip to main content </a>
La valeur #main
dans l'attribut href
envoie le focus clavier à l'élément de page qui comporte l'attribut id="main"
.
Pour que cet élément de page reçoive le focus du clavier, j'avais besoin d'ajouter un attribut tabindex
au conteneur :
<main className="main" id="main" tabIndex="-1"> { props.children() } </main>
L'ajout de la valeur tabindex
de -1
permet à un élément non focalisable de recevoir le focus par programmation, mais est laissé en dehors de l'ordre de tabulation naturel.
Le résultat
Avec la navigation par saut en place, les personnes utilisant un clavier peuvent ignorer des régions répétées comme la zone de navigation latérale pour accéder facilement à la section de contenu principale.
Découvrez le changement de code complet dans le PR (Pull Request): Ajout du lien de saut #4175 .
Amélioration de l'accessibilité n° 2 : étiquette manquante dans le champ de recherche
J'ai remarqué qu'il manquait une label
dans le champ de input
de la recherche. Avoir une label
associée pour chaque input
de formulaire est la clé d'une expérience utilisateur réussie. Pourquoi?
Le problème
Lorsqu'il manque une label
aux champs de input
, les lecteurs d'écran ne sont pas en mesure de décrire avec précision l'objectif du champ. Imaginez un instant un lien sans texte ; à quoi sert ce lien ?
La solution
Celui-ci était assez simple. Ajouter une label
à une input
consiste à créer l'élément label
avec un attribut for
, puis à l'associer à une input
avec un id
.
Afin de ne pas perturber la conception actuelle du site, j'ai également ajouté le prop srOnly
pour que l' label
soit masquée visuellement.
L' label
était codée comme suit :
<ControlLabel htmlFor="searchInput" srOnly={ true }> Search </ControlLabel>
Ensuite, pour le contrôle input
existant, j'ai simplement ajouté la id='searchInput'
.
Le résultat
Désormais, lorsque les utilisateurs de lecteurs d'écran accèdent au champ de recherche, ils entendent la valeur de l' label
"recherche" et ont plus de contexte sur ce qui est attendu.
Découvrez le changement de code complet dans le PR : Search input a11y updates #4123 .
Amélioration de l'accessibilité n° 3 : ajustements des rôles dans la barre latérale
Lors de l'inspection de la source HTML, j'ai remarqué que certains des éléments de la barre latérale comportaient de manière incorrecte des attributs role="presentation"
. J'ai également remarqué que certains éléments étaient marqués comme div
s au lieu d'un balisage sémantique approprié. Cela nécessitait quelques ajustements. Pourquoi?
Le problème
Deux problèmes existaient avec cette section du site :
- Lorsque vous appliquez
role="presentation"
sur un élément, cela supprime toute signification sémantique. En d'autres termes, lorsqu'un lecteur d'écran rencontre l'élément, il n'y a aucune annonce significative pour informer l'utilisateur à quoi sert l'élément. Imaginez un lien sur une page, mais son texte est de la même couleur que le texte du contenu et sans soulignement. Comment sauriez-vous qu'il s'agissait d'un lien ? - L'autre problème ici est lorsque les éléments
div
sont utilisés pour baliser une structure significative. Comme vous le savez peut-être, les élémentsdiv
n'ont aucune signification sémantique et sont généralement réservés pour créer une structure sur une page. Dans les cas où ils sont utilisés à la place d'éléments sémantiques natifs, vous devez appliquer l'attribut derole
approprié pour transmettre cette signification.
La solution
- Pour chaque élément et lien de la liste de navigation, j'ai simplement supprimé le
role
prop afin de permettre à la signification sémantique de transparaître pour les utilisateurs de lecteurs d'écran. - Pour les composants dynamiques qui ont généré des éléments
div
, j'ai appliqué les accessoires derole
appropriés, y comprisrole="list"
pour le composantPanelGroup
etrole="listitem"
pour toutes les instances du composantPanel
.
Le résultat
Une fois les accessoires de role
ajustés, les utilisateurs de lecteurs d'écran entendront des annonces claires et précises lorsqu'ils rencontreront ces éléments, notamment :
- Les instances du composant
Link
seront annoncées comme un élément "link" — très important, et ; - Les éléments des composants
PanelGroup
etPanel
seront annoncés comme un élément "liste" . En conséquence, le nombre total d'articles sera également annoncé, donnant le contexte du nombre d'articles disponibles sur le voyage à venir.
Découvrez le changement de code complet dans le PR : Side nav a11y updates #4093 .
Amélioration de l'accessibilité n° 4 : disponibilité des résultats de recherche non annoncée
En tant qu'utilisateur voyant, j'étais conscient du succès d'une recherche car la zone de contenu principale changeait de contenu pour présenter une liste d'éléments. Mais qu'en est-il d'un utilisateur aveugle de lecteur d'écran ?
Le problème
Si un utilisateur de lecteur d'écran saisissait le texte de recherche et appuyait sur Enter
, rien ne serait annoncé indiquant une recherche réussie ou des résultats. Comment savoir quand des articles sont disponibles afin d'avancer et de découvrir ce nouveau contenu ?
La solution
Pour que le nombre de résultats actuel soit annoncé, j'ai créé une nouvelle région aria-live
, visuellement cachée. Cette région est peuplée de nouveau contenu lorsque de nouveaux résultats de recherche sont présents.
La région est balisée à l'aide d'un div
avec quelques attributs supplémentaires :
-
aria-live="polite"
crée la région "live" et indique aux lecteurs d'écran d'attendre que les autres processus soient terminés avant d'annoncer son contenu. -
aria-atomic="true"
indique aux lecteurs d'écran d'annoncer tout le texte de la région, pas seulement le texte modifié. -
role="status"
définit l'attente pour les lecteurs d'écran d'interpréter le contenu en direct comme des informations "consultatives". En d'autres termes, c'est assez important, mais pas critique (car les gens pourraient naviguer et découvrir du contenu par eux-mêmes.)
Voici à quoi ressemble l'extrait de code final :
<div aria-atomic="true" aria-live="polite" className="sr-only" role="status"> {`${results.length} result${results.length === 1 ? '' : 's'} found`} </div>
Notez l'utilisation du littéral de modèle ES6 pour interpoler le contenu ainsi que pour exécuter une instruction conditionnelle ternaire pour ajuster un état pluriel ou singulier.
Le résultat
Désormais, avec un lecteur d'écran actif, après avoir soumis un terme de recherche, le nombre de résultats sera annoncé par une technologie d'assistance : "20 résultats trouvés !"
Découvrez le changement de code complet dans le PR : Annonces de résultats de recherche #5137 .
Amélioration de l'accessibilité n° 5 : gestion du focus sur les liens de la barre latérale
J'ai remarqué lors de la navigation avec un clavier, après avoir cliqué sur un lien pour charger le contenu de la page, l'indicateur de focus restait sur l'élément en cours. C'était un problème. Pourquoi?
Le problème
Sans une gestion appropriée de la mise au point, les utilisateurs de clavier uniquement ou de lecteur d'écran devraient naviguer dans toute la barre latérale de navigation pour accéder au contenu de la page. Non seulement cela, il n'y a pas non plus d'annonce audible alertant l'utilisateur que quelque chose s'est produit sur l'événement click()
.
La solution
Le correctif que j'ai fini par utiliser était un peu un hack. Normalement, vous devez créer un accessoire ref
sur le conteneur de contenu, puis passer l'objet ref
de haut en bas au composant qui génère les éléments de lien de la barre latérale, puis définir focus()
sur le conteneur sur click()
. Ce n'était pas une solution possible car le site utilisait quelque chose appelé Gatsby et il y avait un problème avec le passage d'objets aux composants Link
? Je ne suis pas vraiment sûr du problème, mais il n'a tout simplement pas coopéré.
Pour contourner cette limitation, ma solution est la suivante :
- J'ai ajouté un
data-navitem="true"
à chacun des composantsLink
de la barre latérale appropriés. - Sur l'événement
click()
, le composantArticle
se charge avec le contenu demandé, en définissantdocument.activeElement
sur l'élément de lien cliqué. - Dans la méthode
componentWillMount()
du composantArticle
, je vérifie si l'élément actuellement ciblé (le lien de la barre latérale viadocument.activeElement)
possède l'attributdata-navitem
. - Si cette condition est
true
, déplacez le focus du clavier vers l'élémentarticle
.
Le résultat
Désormais, lorsqu'une personne utilisant le clavier active l'un des liens de sous-navigation à partir de la barre latérale, le focus du clavier se déplace vers le conteneur de contenu de l' article
. Et cela fournit également un contexte aux utilisateurs de lecteurs d'écran, indiquant que quelque chose s'est passé sur click()
.
Découvrez le changement de code complet dans le PR: NavItem focus #7818 .
Et là, nous l'avons! Avec ces quelques ajustements, l'accessibilité et la convivialité du site freeCodeCamp Guide ont bien augmenté ! Les gens peuvent utiliser le site plus confortablement avec facilité et succès.
Ceci est juste un aperçu de haut niveau de quelques problèmes que j'ai abordés, mais je sais qu'il y a plus à faire. Tout le monde sur le repo freeCodeCamp Guide était très sympathique et désireux d'aider à répondre à mes questions de débutant sur React, alors n'hésitez pas si vous voulez aider !
Bon piratage ! 💻😄💖