Menus déroulants accessibles

Sophie Schuermans le 16/04/2015

Les menus déroulants sont censés simplifier la vie des utilisateurs en leur donnant accès à toutes les pages d'un site. Mais dans la pratique ils sont souvent difficiles à utiliser ou carrément inutilisables.

exemple de menu déroulant à 4 niveaux

Nous essayons ici de résumer les points essentiels auxquels il faut faire attention et de décrire quelques bonnes solutions.

Conseils généraux

Les deux points essentiels auxquels ils faut penser sont les suivants :

  • Utiliser une liste de liens avec un ou plusieurs niveaux d'imbrication pour structurer le menu dans le code HTML. De cette manière la structure du menu est claire pour tout le monde.
  • Faire en sorte que tous les niveaux du menu déroulant soient accessibles, quel que soit le mode d'interaction: souris, clavier, lecteur d'écran ou autres.

À côté de cela on peut également donner des informations supplémentaires :

  • Identifier la liste imbriquée comme un menu de navigation (avec <nav role="navigation">)
  • Annoncer que les liens du premier niveau du menu permettent d'afficher un sous-menu (aria-haspopup="true")
  • Annoncer l'état des éléments du menu : ouvert ou fermé (aria-expanded="true" ou aria-expanded="false" )

De bonnes solutions

La bonne solution dépend du contexte. L'objectif est que tout le monde puisse facilement s'orienter et naviguer dans le site, quel que soit le mode d'interaction utilisé.

On peut diviser les menus déroulants en deux grandes catégories. Les principales distinctions concernent:

  • ce qu'il faut faire pour afficher le sous-menu : s'affiche-t-il au survol de la souris (hover) ou faut-il cliquer, au clavier s'affiche-t-il avec TAB ou ENTER ?
  • la manière dont les sous-menus sont cachés : offscreen (ou clipping) ou display:none.

Il existe pas mal de combinaisons. Nous avons choisi de présenter deux solutions qui fonctionnent bien.

TAB et positionnement offscreen

Exemples : menu déroulant responsive basé sur un exemple de Simply Accessible et démo de menu déroulant accessible proposé par Accede Web. Le premier est responsive, le deuxième pas, mais à part cela leur comportement est semblable.

menu déroulant AnySurfer

menu déroulant AnySurfer sur mobile :affiché comme liste imbriquée

Le comportement du menu est le suivant:

  • A la souris:
    • Le sous-menu s'affiche au survol de l'élément parent.
    • En cliquant sur l'élément parent on navigue vers la page correspondante
  • Au clavier:
    • Le sous-menu s'affiche avec TAB, quand le focus arrive sur l'élément parent.
    • ENTER sert à naviguer vers la page correspondante
    • Le contenu de la liste imbriquée peut être parcourue de haut en bas au moyen du TAB, dans l'ordre du code source.
  • Avec un lecteur d'écran:
    • Le menu dans son entièreté est visible en permanence, comme une simple liste imbriquée car les sous-menus sont cachés de manière à rester visibles pour un lecteur d'écran (offscreen ou clipping). Il n'est donc pas nécessaire d'utiliser aria-haspopup ou aria-expanded.
    • Tous les liens du menu sont toujours visibles dans la liste de liens du lecteur d'écran.
    • Le menu peut se parcourir simplement en utilisant la flèche vers le bas, dans l'ordre du code source.

Cette solution est recommandée quand les liens du premier niveau sont des liens vers des pages du site.

Cette solution n'est pas pratique quand le menu déroulant est très long car il faut faire beaucoup de tabulations pour le traverser. Dans ce cas, l'utilisation d'un lien d'évitement (aller au contenu) peut être une solution.

ENTER et display:none

Exemple: Adobe accessible mega menu.

menu déroulant d'Adobe

Le comportement du menu est le suivant:

  • Au clavier:
    • Le TAB ne parcourt que les liens du premier niveau, qui sont visibles.
    • Le sous-menu s'affiche avec ENTER.
    • Le TAB permet de parcourir le sous-menu quand il est affiché.
  • Avec un lecteur d'écran:
    • Seul le premier niveau du menu est visible en permanence.
    • Les sous-menus sont cachés avec display:none.
    • Le lecteur d'écran annonce que l'élément parent sert à afficher un menu déroulant (grâce à aria-haspopup) et indique si le menu est actuellement déroulé ou pas (grâce à aria-expanded).

Le gros avantage de cette solution est que l'utilisateur qui parcourt le menu au clavier n'est pas obligé de parcourir tous les niveaux de la liste.

Pour ce même comportement au clavier, il y a trois variantes, en fonction de la fonction des éléments du premier niveau du menu :

  1. Uniquement afficher et masquer le sous-menu
  2. Afficher le sous-menu et ouvrir une page du site
  3. Uniquement ouvrir une page du site (accompagnés d'un bouton pour afficher et masquer sous-menu)

Première variante

Les liens du menu servent uniquement à afficher et masquer les sous-menus. Les liens du premier niveau du menu ne correspondent pas à des pages du site.

  • A la souris: le sous-menu s'affiche quand on clique sur l'élément parent. Un deuxième clic masque le sous-menu.
  • Au clavier: Le premier ENTER affiche le sous-menu, le deuxième ENTER le masque.

C'est une bonne solution quand il n'y a pas de pages intermédiaires correspondant au premier niveau du menu.

Deuxième variante

Exemple sur la page du FWO

Les liens du menu ont une double fonction:

  • A la souris: le sous-menu s'affiche au survol de l'élément parent. En cliquant sur l'élément parent on navigue vers la page correspondante
  • Au clavier: Le premier ENTER affiche le sous-menu. Le deuxième ENTER sur le même lien ouvre la page correspondante.

Ce type de menu peut porter à confusion car le même lien a deux fonctions. Certains ne comprendront pas que le lien sert également à afficher une page, et ne découvriront pas ce contenu.

Troisième variante

Exemple sur Screenfeed.

Les liens du menu servent à afficher une page et ils sont accompagnés d'un bouton séparé pour dérouler le menu.

menu déroulant 'poney' avec bouton pour dérouler le menu

C'est une bonne solution quand les éléments du menu ont une double fonction. Il faut veiller à bien intituler les boutons.

Alternative au menu déroulant : sous-menus sur les pages

Exemple: menu déroulant sur le site de la ville de Leuven : le menu déroulant sous 'Ville de la bière' ne peut pas s'afficher au clavier et est invisible avec un lecteur d'écran. Mais en utilisant le lien "Ville de la bière" on trouve un sous-menu qui contient les mêmes liens que le menu déroulant:

menu déroulant 'Ville de la bière' sous-menu dans la colonne de gauche, contenant les mêmes liens

  • Le sous-menu s'affiche au survol de la souris.
  • Le sous-menu ne peut pas s'afficher au clavier (ni avec TAB, ni avec ENTER).
  • Seul le premier niveau du menu est visible en permanence. Les sous-menus sont cachés avec display:none.
  • Un sous-menu identique au menu déroulant est disponible sur toutes les pages accessibles à partir du menu.

Ceci peut être une solution quand le menu déroulant est trop long. Il faut cependant veiller à ce que le sous-menu puisse facilement être trouvé et identifié comme tel sur toutes les pages.

Erreurs à éviter

En pratique on rencontre régulièrement des menus de navigation déroulants qui ne sont pas accessibles, pour diverses raisons. Voici quelques erreurs à éviter:

  • Le menu déroulant se parcourt uniquement avec les flèches, pas avec le TAB: ce n'est pas le comportement attendu dans une page web mais dans une application.
  • Les rôles menu, menubar ou menuitem sont utilisés : ces rôles sont destinés aux menus applicatifs, pas aux menus de navigation, et ils escamotent la sémantique présente dans le code HTML (listes, liens). Ne les utilisez pas pour des menus de navigation.
  • Le TAB permet d'accéder à tous les liens mais ils ne deviennent pas visibles. Il faut faire en sorte que les parties déroulantes soient visibles quand elles ont le focus.
  • Les liens du menu déroulant sont accessibles mais n’envoient pas vers la page annoncée (exemple: bug sur un module Superfish pour Drupal).
  • Les liens du menu ne sont pas des liens.
  • Le menu n'est pas structuré comme une liste imbriquée, l'ordre des liens n'est pas correct.
Réagissez

Supernova, lecteur d'écran inadapté pour le surf

Pierre Jourdain le 14/04/2015

Certains sites web accessibles sont inutilisables si on les visite avec Supernova. Vous naviguez beaucoup et utilisez un lecteur d'écran? Il vaut mieux dans ce cas utiliser soit NVDA pour Windows ou VoiceOver sur Mac. Les deux sont gratuits! Le logiciel commercial Jaws est une autre excellente alternative. Voici pourquoi:

Rafraîchissement des pages

Les sites Web sont plus interactifs que jamais. Vous ne faites pas que lire, vous faites de plus en plus de choses: se connecter et créer un profil, publier un commentaire sur un article de blog, etc. Ces actions se produisent au sein d'une page Web, souvent sans rafraîchir la page. Cela s'appelle un chargement "asynchrone" ou dynamique. Un nouveau contenu est chargé et une partie de la page change. Ceux qui ne peuvent voir ces changements sont en difficulté. Voici quelques exemples sur le nouveau site de De Lijn.

De Lijn

Perturbation des services

Lorsque les bus ne circulent pas, en raison d'une grève par exemple, la page d'accueil du site affiche une fenêtre de dialogue informant les visiteurs des perturbations. Les lecteurs d'écrans déplacent le focus directement sur celle-ci. Ce n'est pas le cas de Supernova.

fenêtre de dialogue Perturbations des services

Les fenêtres de dialogue sont fréquentes sur le web. Dialog, lightbox, overlay ou pop-up sont des synonymes. Le principe est toujours le même. Un clic sur un lien ou un bouton affiche une fenêtre de dialogue par-dessus le contenu de la page. Les formulaires de connexion s'affichent dans des fenêtres de dialogue. Dans les applications bancaires en ligne, l'utilisateur reçoit une notification et pour prolonger sa session, il doit cliquer dans cette fenêtre de dialogue.

Lorsque une telle fenêtre s'ouvre sans que la page ne se rafraîchisse, l'utilisateur n'en est pas informé. Le lecteur d'écran ne communique pas automatiquement cette information. Même si grâce à son expérience, l'utilisateur se doute qu'une fenêtre vient de s'ouvrir, il ne peut savoir où elle se trouve. Le lecteur d'écran pourrait lire le contenu de cette fenêtre, mais il ne peut savoir où elle se trouve. Généralement le contenu se trouve en bas de page. Heureusement il existe une solution. Le développeur déplace le 'focus' du lecteur d'écran sur la fenêtre de dialogue. Un clic par exemple sur le bouton 'Se Connecter', ouvre une fenêtre de dialogue et le lecteur d'écran se positionne au début du formulaire. Ceci est rendu possible par une simple instruction en Javascript, la fonction 'focus'. Le déplacement du focus est crucial pour rendre les rafraîchissements de pages accessibles pour les lecteurs d'écran.

Supernova ne gère pas les déplacements de focus. NVDA, Jaws, VoiceOver et d'autres lecteurs d'écran le font très bien.

Itinéraires possibles

Lorsque vous entrez un lieu de départ et d'arrivée dans le calculateur d'itinéraires, vous obtenez une liste de routes possibles, suivie du détail de l'itinéraire actif. Si vous cliquez un itinéraire différent dans la liste, le détail de l'itinéraire actif change sans rafraîchir la page. Les itinéraires possibles ne sont pas des liens vers une nouvelle page. Ils modifient l'itinéraire affiché sur la page. Un bon lecteur d'écran déplacera le focus au titre "Itinéraire avec départ à..." au-dessus du détail de l'itinéraire. Avec Supernova rien ne se passe. Le focus reste sur le lien dans la liste.

Calculateur d'itinéraires avec plusieurs itinéraires

Arrêts

Le troisième exemple concerne les onglets. La page de détail d'un arrêt possède deux onglets: 'Passages en ce moment' et 'Toutes les lignes de passage'. Un clic sur l'un des onglets n'ouvre pas de nouvelle page. Seul le contenu sous les onglets est modifié. Un clic sur l'onglet 'Toutes les lignes de passage' fait disparaître le contenu de l'onglet 'Passages en ce moment' et affiche la liste de toutes les lignes de passage. Le focus du lecteur d'écran se déplace alors sur le titre qui précède le contenu. Supernova ne le fait pas.

Arret Gent Sint-Jacobs

Conclusion

AnySurfer demande aux développeurs web de rendre les rafraîchissements dynamiques compréhensibles pour les lecteurs d'écran. Ils gèrent donc le déplacement du focus. Supernova ne le gère pas. Il est possible de parcourir le site de De Lijn et d'autres sites modernes avec Supernova mais il ne sera pas possible d'accéder aux contenus dynamiques. Les lecteurs d'écran comme JAWS, NVDA et VoiceOver assurent une navigation plus aisée. Sur un site accessible, ils déplaceront le focus au début du contenu dynamique.

Réagissez

Le défilement infini

Pierre Jourdain le 13/04/2015

Le défilement infini ou Infinite scrolling est une technique qui consiste à charger automatiquement le contenu de la page lorsque l'utilisateur atteint le bas de celle-ci. C'est le cas, par exemple, de la ligne du temps du profil Facebook.

C'est une alternative à la traditionnelle pagination que l'on trouve, entre autres, dans le bas de la page des résultats de recherche de Google.

Capture d'écran avec deux fenêtres côte à côte. La première utilise la pagination traditionelle et l' autre utilise l'infinite scrolling
Source Smashing Magazine

Le défilement infini présente des avantages, notamment sur un appareil mobile. Il permet d'économiser de l'espace sur l'écran et l'utilisateur peut, simplement en glissant son doigt sur l'écran, faire apparaître du contenu supplémentaire.

The advantage of not having to acquire and click “next page” keeps audiences engaged with the content and less focused on the mechanics of navigating to the next page.

Hoa Loranger Norman Nielsen Group

Cette technique présente malheureusement beaucoup d'inconvénients.

Accessibilité

  • Cette technique est incompatible avec la présence d'un pied de page. L'apparition automatique de nouveau contenu repousse à chaque fois le pied de page vers le bas. Celui-ci ne sera donc jamais atteint. Le contenu ajouté dynamiquement doit donc être le dernier contenu de la page.
  • C'est un comportement inattendu et non sollicité. C'est déroutant pour quelqu'un qui n'a pas de vue d'ensemble de l'écran. L'utilisateur doit toujours avoir le contrôle sur la page. Le nouveau contenu devrait donc être chargé lorsque l'utilisateur le demande. Ceci peut être facilement résolu en ajoutant un bouton "Charger plus de résultats".

Usability

Le déroulement infini peut être une option pour des sites où tout le contenu est de même niveau. C'est le cas, par exemple, des sites Facebook, Pinterest et Twitter. Pour les sites web applicatifs (recherche de produits, commandes en ligne, comparateurs de prix...), cette technique présente trop d'inconvénients.

Le déroulement infini:

  • rend difficile la recherche dans une page.
  • est désorientant. L'utilisateur ne voit pas où il se trouve. La barre de défilement ne représente pas correctement la longueur de la page.
  • limite le contrôle de l'utilisateur. Il ne peut pas atteindre le bas de la page.
  • crée une fatigue psychologique, l'utilisateur n'a pas de liste mentale de la page.
  • rend la navigation difficile, l'utilisateur ne peut pas accéder directement à une page, ce qui, par contre, est possible avec la pagination.

Sources

Conclusion

Ne l'utilisez pas pour les sites web orientés tâches. Pour ces cas, la pagination numérotée est plus adaptée. Si le contenu de votre site s'y prête, ajoutez plutôt un bouton "charger plus de messages" . Testez avec le clavier ainsi qu'avec un lecteur d'écran.

Réagissez

Be-hackathon : des apps pour les personnes handicapées

Pierre Jourdain le 03/04/2015

Plus de 70 étudiants ont participé au premier Be-hackathon qui a eu lieu les 26, 27 et 28 mars à l'initiative de Be.Wan dans les locaux du Wagon, au sein de l’espace de coworking co.station. Chaque équipe de quatre développeurs devait relever le même défi : développer en 36 heures une application pour mobile qui aiderait les personnes handicapées dans leur quotidien.

AnySurfer avait été invité à contribuer à la soirée de lancement du 18 mars. Après la présentation de l’organisation du week-end par Gilles Boon de Be.Wan, les représentants du Creth ont pris la parole pour expliquer comment les personnes handicapées utilisent les smartphones et tablettes dans leur quotidien. Vincent Collin a insisté sur l'importance de tester les applications avec plusieurs utilisateurs.

Notre collègue Bart De Clercq a fait un tour d'horizon des différentes options d'accessibilité disponibles sur iOS et Androïd. Nous avons vu que ces options permettent de faire énormément de choses. Par contre des applications en apparence assez simple ne sont pas accessibles si elles sont mal conçues. Bart a cité l'exemple de l'application d'Uber qui était accessible et beaucoup utilisée par des personnes aveugles mais dont le bouton principal est devenu inutilisable avec VoiceOver suite à une mise à jour de l'application.

Les développeurs ont donc une grande responsabilité lorsqu'ils développent des applications : Le design et la manière dont elle est codée sont déterminants pour son accessibilité. Bart a conclu en donnant quelques pistes pour développer des apps accessibles.

Après les présentations, nous avons eu l’occasion de rencontrer les participants du hackathon, très motivés. Des personnes handicapées étaient également présentes pour répondre aux questions, réagir aux idées des étudiants ou exprimer leurs propres besoins.

Le dimanche 28 mars le jury a sélectionné quatre applications. Bien qu'elle ne soient pas tout à fait fonctionnelles, ces applications laissent entrevoir un très beau potentiel. Mais nous n’avons pas eu l’occasion d'examiner leur accessibilité.

Première place : Metro

Cette application principalement destinée aux personnes aveugles ou malvoyantes. Le problème initial est qu’il est terriblement compliqué pour ces personnes d’utiliser les transports publics. Souvent, sur un même quai, plusieurs lignes sont desservies et aucun indicateur non visuel permet d’être tenu informé de quel métro arrive en station.

L’application résout le problème en annonçant à haute voix le numéro du métro, ainsi que sa destination, lors de son arrivée en station.

Elle se connecte aux API fournies par les sociétés de transports en commun (pour la démo, ce fût le réseau de métro Londonien)

Deuxième place : EasyVoice

Le contexte initial : un membre de l’équipe est papa d’un enfant souffrant d’un handicap lui rendant, entre autres, l’usage de la parole assez difficile. L’enfant utilise couramment une application sur tablette lui permettant d’énoncer des phrases préenregistrées. L’inconvénient majeur de cette solution est que l’enfant doit transporter une tablette – ce qui est loin d’être facile pour lui.

L’application fonctionne sur une smartwatch et ne nécessite aucune connexion à Internet. L’enfant peut donc utiliser cet outil à tout moment, directement sur son poignet.

Troisième place : Swipe

Cette application simplifie à l’extrême l’utilisation d’un téléphone. Elle est destinée aux personnes pour lesquelles l'utilisation d'un téléphone est trop compliquée, comme par exemple une personne atteinte de la maladie d'Alzheimer.

Swipe permet de créer des raccourcis aux fonctionnalités du téléphone via deux moyens :

  • Dessiner une forme sur l’écran
  • Approcher le téléphone d’un tag NFC : Le simple fait d’approcher le téléphone sur un tag lancera, par exemple, un appel vers un membre de la famille ou vers un service de secours.

Quatrième place : Pin It

Destinées aux personnes aveugles ou malvoyantes, l’application utilise également des étiquettes NFC. Elle fonctionne sur le principe du labelpen. L’idée est d’apposer des étiquettes NFC sur tous les objets du quotidien : brique de lait, médicaments, vêtements, etc. Ensuite, l’utilisateur posera son téléphone sur un objet étiqueté (un médicament, par exemple) et celui-ci dictera à haute-voix les informations.

Réagissez

Contenu généré par CSS

Sophie Schuermans le 01/10/2014

HTML pour le contenu, CSS pour la mise en forme : ce mantra a toujours été considéré comme la base d'un web de qualité. C'est également un plus pour l'accessibilité. Et pourtant il nous arrive régulièrement d'introduire par l'intermédiaire du CSS du contenu significatif dans une page web. Il n'est pas toujours possible de rendre ce contenu accessible pour tout le monde. La meilleure règle reste donc d'utiliser CSS uniquement pour la mise en forme et de mettre le contenu dans le markup ou éventuellement de l'introduire dans le DOM au moyen de Javascript.

Images insérées au moyen de CSS (background, :before ou :after)

La liste de directives AnySurfer contient un point sur les images d'arrière-plan porteuses d'information. Le plus simple est de ne pas insérer d'images porteuses d'information au moyen de CSS, mais c'est quand même une pratique courante (utilisation de sprites, par exemple):

<a class="twitter" href="https://twitter.com/anysurfer"></a>
a.twitter:after { 
    content:url('icon_twitter.png'); 
}

L'image d'arrière-plan est invisible pour un lecteur d'écran et il n'est pas possible d'y ajouter un attribut alt. Ce qui reste est donc un lien vide sans aucune signification. Pour corriger cela il faut ajouter texte de remplacement caché :

<a class="twitter" href="https://twitter.com/anysurfer">
<span class="visuallyhidden">Twitter</span>
</a>

Dans l'exemple ci-dessus, l'image est insérée avec :after. Dans le cas d'une image porteuse d'information c'est une meilleure solution que background. Lorsqu'un utilisateur malvoyant active le mode haut contraste de Windows, les images d'arrière-plan (insérées avec background) sont supprimées mais les feuilles de style ne sont pas désactivées donc le contenu caché reste caché et le lien de l'exemple ci-dessus serait invisible. Avec :after, l'image n'est pas supprimée en mode haut contraste et le lien reste visible.

Texte inséré avec :before et :after

Les pseudo-éléments :before et :after permettent d'intercaler du contenu (texte ou image) dans une page web. C'est parfait pour ajouter des éléments décoratifs comme par exemple un tiret entre les liens d'un menu horizontal. Mais il ne faut pas utiliser cette technique pour insérer de l'information comme dans cet exemple (insertion de texte avec :after).

Le contenu inséré par CSS ne fait pas partie du DOM et n'est donc normalement pas disponible pour les lecteurs d'écran. On pourrait donc penser dans ce cas que ce serait une bonne idée d'ajouter un texte caché comme pour les images porteuses d'information. Mais ce n'est pas le cas.

Nos tests ont montré qu'en réalité presque tous les navigateurs transmettent ce contenu aux lecteurs d'écran, mais Internet Explorer ne le transmet pas. En ajoutant un texte caché, le contenu sera lu deux fois dans tous les navigateurs sauf internet explorer. Ce n'est pas une bonne solution.

Il ne faut donc pas injecter de contenu textuel au moyen de CSS, mais mettre ce contenu dans le code HTML, ou éventuellement l'y insérer au moyen de JQuery. Dans cet exemple (insertion de texte avec JQuery) nous ajoutons une indication du format PDF à tous les liens vers des fichiers PDF, sans rien modifier au markup.

<script>
	$('a[href$=".pdf"]').each(function(){
	    $(this).append(' (PDF)');
	});
</script>

Polices d'icônes (icon fonts)

Les polices d'icônes sont un cas particulier. La police d'icônes associe des icônes à des caractères Unicodes. Le caractère Unicode est souvent inséré par l'intermédiaire des pseudo-éléments CSS :before et :after comme décrit plus haut. Mais la signification visuelle de l'icône affichée n'a rien à voir avec le caractère inséré que le lecteur d'écran prononce. Voir des exemples d'utilisation plus ou moins accessible de polices d'icônes.

Pour que l'information véhiculée par l'icône soit accessible, il faut

  • prévoir un texte de remplacement significatif, comme pour une image d'arrière-plan,
  • et faire en sorte que le caractère ne soit pas lu. Cela peut se faire de deux manières:
    • Choisir un caractère Unicode qui fait partie du private use area. Les lecteurs d'écran ne les lisent pas.
    • Si vous utilisez des caractères lisibles, cachez-les avec aria-hidden="true".

Conclusion

Karl Groves résume très bien le sujet dans cet article: CSS generated content is not content: si c'est une information, ne l'insérez pas par du CSS. Si c'est décoratif, utilisez CSS.

Réagissez