Ce tutoriel explique comment créer une navigation principale accessible pour un site Web. Vous découvrirez le HTML sémantique, l'accessibilité et comment l'utilisation d'attributs ARIA peut parfois faire plus de mal que de bien.
Il existe de nombreuses façons de créer la navigation principale d'un site Web, en termes de style, de fonctionnalités, de balisage sous-jacent et d'informations sémantiques. Si l'implémentation est trop minimaliste, elle fonctionne pour la plupart des utilisateurs, mais l'expérience utilisateur (UX) n'est peut-être pas optimale. Si elle est trop complexe, elle risque de dérouter les utilisateurs, voire de les empêcher d'y accéder.
Pour la plupart des sites Web, vous devez créer une structure qui ne soit ni trop simple, ni trop complexe.
Création couche par couche
Dans ce tutoriel, vous allez commencer par une configuration de base, puis ajouter des fonctionnalités couche par couche jusqu'à fournir juste assez d'informations, de style et de fonctionnalités pour satisfaire la plupart des utilisateurs. Pour ce faire, vous utilisez le principe d'amélioration progressive, qui consiste à commencer par la solution la plus fondamentale et la plus robuste, puis à ajouter progressivement des couches de fonctionnalités. Si une couche ne fonctionne pas pour une raison quelconque, la navigation fonctionnera toujours, car elle basculera de manière fluide vers la couche sous-jacente.
Structure de base
Pour une navigation de base, vous avez besoin de deux éléments : des éléments <a> et quelques lignes de CSS pour améliorer le style et la mise en page par défaut de vos liens.
HTML
<a href="/home">Home</a> <a href="/about-us">About us</a> <a href="/pricing">Pricing</a> <a href="/contact">Contact</a>CSS
/* Define variables for your colors */ :root { --color-shades-dark: rgb(25, 25, 25); } /* Use the alternative box model Details: <https://web.dev/learn/css/box-model/> */ *{ box-sizing: border-box; } /* Basic font styling */ body { font-family: Segoe UI, system-ui, -apple-system, sans-serif; font-size: 1.6rem; } /* Link styling */ a { --text-color: var(--color-shades-dark); border-block-end: 3px solid var(--border-color, transparent); color: var(--text-color); display: inline-block; margin-block-end: 0.5rem; /* See note at the bottom of this chapter */ margin-inline-end: 0.5rem; padding: 0.1rem; text-decoration: none; } /* Change the border-color on :hover and :focus */ a:where(:hover, :focus) { --border-color: var(--text-color); }
Cette technique fonctionne bien pour la plupart des utilisateurs, quel que soit le mode d'accès au site. La navigation est accessible avec une souris, un clavier, un appareil tactile ou un lecteur d'écran, mais des améliorations sont possibles. Vous pouvez améliorer l'expérience en étendant ce modèle de base avec des fonctionnalités et des informations supplémentaires.
Voici ce que vous pouvez faire :
- Mettez en surbrillance la page active.
- Annoncez le nombre d'éléments aux utilisateurs de lecteurs d'écran.
- Ajoutez un repère et permettez aux utilisateurs de lecteurs d'écran d'accéder directement à la navigation à l'aide d'un raccourci.
- Masquez la navigation sur les fenêtres d'affichage étroites.
- Améliorer le style de la sélection
Mettre en surbrillance la page active
Pour mettre en évidence la page active, vous pouvez ajouter une classe au lien correspondant.
<a href="/about-us" class="active-page">About us</a>
Le problème avec cette approche est qu'elle transmet l'information sur le lien actif de manière purement visuelle. Un utilisateur aveugle de lecteur d'écran ne pourrait pas faire la différence entre la page active et les autres pages. Heureusement, la norme ARIA (Accessible Rich Internet Applications) permet également de communiquer ces informations de manière sémantique. Utilisez l'attribut et la valeur aria-current="page" au lieu d'une classe.
aria-current (état) indique l'élément qui représente l'élément actuel dans un conteneur ou un ensemble d'éléments associés.
Jeton de page utilisé pour indiquer un lien dans un ensemble de liens de pagination, où le lien est stylisé visuellement pour représenter la page actuellement affichée.
[Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)
Avec l'attribut supplémentaire, un lecteur d'écran annonce désormais quelque chose comme "page actuelle, lien, À propos de nous" au lieu de simplement "lien, À propos de nous".
<a href="/about-us" aria-current="page" class="active-page">About us</a>
Un effet secondaire pratique est que vous pouvez utiliser l'attribut pour sélectionner le lien actif en CSS, ce qui rend la classe active-page obsolète.
<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
--border-color: var(--color-highlight);
--text-color: var(--color-highlight);
}
Annoncer le nombre d'éléments
En regardant la navigation, les utilisateurs voyants peuvent dire qu'elle ne contient que quatre liens. Un utilisateur aveugle de lecteur d'écran ne peut pas obtenir ces informations aussi rapidement. Il se peut qu'ils doivent parcourir toute la liste des liens. Cela ne pose pas de problème si la liste est courte, comme dans cet exemple, mais si elle contient 40 liens, cette tâche peut être fastidieuse. Si un utilisateur de lecteur d'écran sait d'avance que la navigation contient beaucoup de liens, il peut décider d'utiliser un moyen de navigation différent et plus efficace, comme la recherche sur le site.
Pour communiquer le nombre d'éléments à l'avance, vous pouvez encapsuler chaque lien dans un élément de liste (<li>), imbriqué dans une liste non ordonnée (<ul>).
<ul>
<li>
<a href="/home">Home</a>
</li>
<li>
<a href="/about-us" aria-current="page">About us</a>
</li>
<li>
<a href="/pricing">Pricing</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
Lorsqu'un utilisateur de lecteur d'écran trouve la liste, son logiciel annonce quelque chose comme "liste, 4 éléments".
Voici une démonstration de la navigation utilisée avec le lecteur d'écran NVDA sous Windows.
Vous devez maintenant adapter le style pour qu'il ressemble à ce qu'il était auparavant.
/* Remove the default list styling and create a flexible layout for the list */
ul {
display: flex;
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
/* Basic link styling */
a {
--text-color: var(--color-shades-dark);
border-block-end: 3px solid var(--border-color, transparent);
color: var(--text-color);
padding: 0.1rem;
text-decoration: none;
}
L'utilisation de listes peut présenter de nombreux avantages pour les utilisateurs de lecteurs d'écran :
- Ils peuvent obtenir le nombre total d'éléments avant d'interagir avec eux.
- Ils peuvent utiliser des raccourcis pour passer d'un élément de liste à un autre.
- Ils peuvent utiliser des raccourcis pour passer d'une liste à l'autre.
- Le lecteur d'écran peut annoncer l'index de l'élément actuel (par exemple, "élément de liste, deux sur quatre").
De plus, si la page est présentée sans CSS, la liste affiche les liens sous la forme d'un groupe d'éléments cohérent, et non d'une simple pile de liens.
Un détail important concernant VoiceOver dans Safari est que vous perdez tous ces avantages lorsque vous définissez list-style: none. Cela est volontaire. L'équipe WebKit a décidé de supprimer la sémantique de liste lorsqu'une liste ne ressemble pas à une liste. Selon la complexité de votre navigation, cela peut poser problème ou non. D'une part, la navigation reste utilisable et cela n'affecte que VoiceOver dans Safari. VoiceOver avec Chrome ou Firefox annonce toujours le nombre d'éléments, tout comme d'autres lecteurs d'écran, tels que NVDA. En revanche, les informations sémantiques peuvent être très utiles dans certaines situations. Pour prendre cette décision, vous devez tester la navigation avec des utilisateurs réels de lecteurs d'écran et recueillir leurs commentaires. Si vous décidez que VoiceOver dans Safari doit se comporter comme tous les autres lecteurs d'écran, vous pouvez contourner le problème en définissant explicitement le rôle de liste ARIA sur <ul>. Cela rétablit le comportement à l'état antérieur à la suppression du style de liste. Visuellement, la liste n'a pas changé.
<ul role="list">
<li>
<a href="/home">Home</a>
</li>
...
</ul>
Ajouter un point de repère
En peu d'efforts, vous avez apporté des améliorations majeures pour les utilisateurs de lecteurs d'écran, mais vous pouvez faire encore mieux. Sémantiquement, la navigation n'est encore qu'une liste de liens, et il est difficile de savoir que cette liste spécifique est la navigation principale de votre site Web. Vous pouvez transformer cette liste ordinaire en liste de navigation en encapsulant <ul> dans un élément <nav>.
L'utilisation de l'élément <nav> présente plusieurs avantages. En particulier, un lecteur d'écran annonce quelque chose comme "navigation" lorsque l'utilisateur interagit avec l'élément, et ajoute un repère à la page. Les points de repère sont des zones spéciales de la page, comme <header>, <footer> ou <main>, vers lesquelles un lecteur d'écran peut accéder. Il peut être utile d'avoir des repères sur une page, car cela permet aux utilisateurs de lecteurs d'écran d'accéder directement aux zones importantes de la page sans avoir à interagir avec le reste de la page. Par exemple, vous pouvez passer d'un repère à un autre en appuyant sur la touche D dans NVDA. Dans VoiceOver, vous pouvez utiliser le rotor pour lister tous les points de repère de la page en appuyant sur VO+U.
Dans cette liste, vous voyez quatre points de repère : banner qui est l'élément <header>, navigation qui est l'élément <nav>, main qui est l'élément <main> et content information qui est l'élément <footer>. Cette liste ne doit pas être trop longue. Vous ne devez marquer comme points de repère que les parties critiques de votre UI, comme la recherche sur le site, la navigation locale ou la pagination.
Si vous avez une navigation sur l'ensemble du site, une navigation locale pour la page et une pagination sur une seule page, vous pouvez également avoir trois éléments <nav>. C'est bien, mais il y a maintenant trois repères de navigation et, sémantiquement, ils se ressemblent tous. Il est difficile de les distinguer, à moins de très bien connaître la structure de la page.
Pour les distinguer, vous devez les libeller à l'aide de aria-labelledby ou aria-label.
<nav aria-label="Main">
<ul>
<li>
<a href="/home">Home</a>
</li>
...
</ul>
</nav>
...
<nav aria-label="Select page">
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
Si le libellé que vous avez choisi existe déjà quelque part sur la page, vous pouvez utiliser aria-labelledby à la place et référencer le libellé existant à l'aide de l'attribut id.
<nav aria-labelledby="pagination_heading">
<h2 id="pagination_heading">Select a page</h2>
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
Un libellé concis suffit, ne soyez pas trop verbeux. Omettez les expressions telles que "navigation" ou "menu", car le lecteur d'écran fournit déjà ces informations aux utilisateurs.
Masquer la navigation sur les fenêtres d'affichage étroites
Personnellement, je ne suis pas fan de masquer la navigation principale sur les fenêtres d'affichage étroites, mais si la liste des liens devient trop longue, il n'y a pas d'autre solution. Dans ce cas, au lieu de la liste, les utilisateurs voient un bouton intitulé "Menu", une icône hamburger ou une combinaison des deux. Cliquez sur le bouton pour afficher ou masquer la liste. Si vous connaissez les bases de JavaScript et de CSS, c'est une tâche réalisable, mais vous devez tenir compte de plusieurs éléments en termes d'expérience utilisateur et d'accessibilité.
- Vous devez masquer la liste de manière accessible.
- La navigation doit être accessible au clavier.
- La navigation doit indiquer si elle est visible ou non.
Ajouter un bouton hamburger
Comme vous suivez le principe d'amélioration progressive, vous devez vous assurer que votre navigation fonctionne toujours et reste logique même si JavaScript est désactivé.
La première chose dont votre navigation a besoin est un bouton hamburger. Vous le créez en HTML dans un élément de modèle, vous le clonez en JavaScript et vous l'ajoutez à la navigation.
<nav id="mainnav">
...
</nav>
<template id="burger-template">
<button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
<svg width="24" height="24" aria-hidden="true">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
</svg>
</button>
</template>
- L'attribut
aria-expandedindique au logiciel de lecture d'écran si l'élément contrôlé par le bouton est développé ou non. aria-labeldonne au bouton un nom dit "accessible", une alternative textuelle à l'icône de menu hamburger.- Vous masquez l'élément
<svg>de la technologie d'assistance à l'aide dearia-hidden, car il comporte déjà un libellé textuel fourni pararia-label. aria-controlsindique à la technologie d'assistance compatible avec l'attribut (par exemple, JAWS) quel élément le bouton contrôle.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');
// Toggle aria-expanded attribute
button.addEventListener('click', e => {
// aria-expanded="true" signals that the menu is currently open
const isOpen = button.getAttribute('aria-expanded') === "true"
button.setAttribute('aria-expanded', !isOpen);
});
// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
if (e.code === 'Escape') {
button.setAttribute('aria-expanded', false);
}
});
// Add the button to the page
nav.insertBefore(burgerClone, list);
- Il est pratique pour les utilisateurs de pouvoir fermer la navigation quand ils le souhaitent, par exemple en appuyant sur la touche Échap.
- Il est important d'utiliser
insertBeforeau lieu deappendChild, car le bouton doit être le premier élément de votre navigation. Si un utilisateur de clavier ou de lecteur d'écran appuie sur Tabulation après avoir cliqué sur le bouton, il s'attend à ce que le premier élément de la liste soit sélectionné. Si le bouton se trouve après la liste, ce n'est pas le cas.
Ensuite, vous réinitialisez le style par défaut du bouton et vous vous assurez qu'il n'est visible que sur les fenêtres d'affichage étroites.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
}
}
/* Reset button styling */
button {
all: unset;
display: var(--nav-button-display, flex);
}
Masquer la liste
Avant de masquer la liste, positionnez et stylisez la navigation et la liste de sorte que la mise en page soit optimisée pour les fenêtres d'affichage étroites, tout en restant esthétique sur les écrans plus grands.
Tout d'abord, supprimez l'élément <nav> du flux naturel de la page et placez-le dans l'angle supérieur de la fenêtre d'affichage.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
}
nav {
position: var(--nav-position, fixed);
inset-block-start: 1rem;
inset-inline-end: 1rem;
}
Ensuite, modifiez la mise en page sur les fenêtres d'affichage étroites en ajoutant une nouvelle propriété personnalisée (—-nav-list-layout). La mise en page est en colonne par défaut et passe en ligne sur les écrans plus grands.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
}
}
ul {
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
Votre navigation devrait ressembler à ceci sur les fenêtres d'affichage étroites.
La liste a évidemment besoin de CSS. Nous allons la déplacer vers le coin supérieur, la faire occuper tout l'écran verticalement, et appliquer un background-color et un box-shadow.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
--nav-list-position: static;
--nav-list-padding: 0;
--nav-list-height: auto;
--nav-list-width: 100%;
--nav-list-shadow: none;
}
}
ul {
background: rgb(255, 255, 255);
box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
height: var(--nav-list-height, 100vh);
list-style: none;
margin: 0;
padding: var(--nav-list-padding, 2rem);
position: var(--nav-list-position, fixed);
inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
width: var(--nav-list-width, min(22rem, 100vw));
}
button {
all: unset;
display: var(--nav-button-display, flex);
position: relative;
z-index: 1;
}
La liste doit ressembler à ceci sur les fenêtres d'affichage étroites, plus à une barre latérale qu'à une simple liste.
Enfin, masquez la liste, ne l'affichez que lorsque l'utilisateur clique une fois sur le bouton, puis masquez-la lorsqu'il clique à nouveau. Il est important de ne masquer que la liste et non l'ensemble de la navigation, car masquer la navigation reviendrait également à masquer un repère important.
Précédemment, vous avez ajouté un événement de clic au bouton pour activer/désactiver la valeur de l'attribut aria-expanded. Vous pouvez utiliser ces informations comme condition pour afficher et masquer la liste en CSS.
@media (min-width: 48em) {
ul {
--nav-list-visibility: visible;
}
}
ul {
visibility: var(--nav-list-visibility, visible);
}
/* Hide the list on narrow viewports, if it comes after an element with
aria-expanded set to "false". */
[aria-expanded="false"] + ul {
visibility: var(--nav-list-visibility, hidden);
}
Il est important d'utiliser une déclaration de propriété telle que visibility: hidden ou display: none au lieu de opacity: 0 ou translateX(100%) pour masquer la liste. Ces propriétés permettent de s'assurer que les liens ne sont pas sélectionnables lorsque la navigation est masquée. L'utilisation de opacity ou translate supprime visuellement le contenu, de sorte que les liens sont invisibles, mais toujours accessibles à l'aide du clavier, ce qui peut être déroutant et frustrant. L'utilisation de visibility ou de display masque visuellement l'élément et le rend inaccessible, ce qui le masque pour tous les utilisateurs.
Animer la liste
Si vous vous demandez pourquoi utiliser visibility: hidden; plutôt que display: none;, c'est parce que vous pouvez animer la visibilité. Il n'a que deux états, hidden et visible, mais vous pouvez le combiner avec une autre propriété comme transform ou opacity pour créer un effet de glissement ou de fondu. Cela ne fonctionnerait pas avec display: none, car la propriété display n'est pas animable.
Le code CSS suivant effectue une transition de opacity pour créer un effet de fondu d'entrée et de sortie.
ul {
transition: opacity 0.6s linear, visibility 0.3s linear;
visibility: var(--nav-list-visibility, visible);
}
[aria-expanded="false"] + ul {
opacity: 0;
visibility: var(--nav-list-visibility, hidden);
}
Si vous souhaitez animer le mouvement, vous devriez envisager d'encapsuler la propriété transition dans une requête média prefers-reduced-motion, car les animations peuvent provoquer des nausées, des vertiges et des maux de tête chez certains utilisateurs.
ul {
visibility: var(--nav-list-visibility, visible);
}
@media (prefers-reduced-motion: no-preference) {
ul {
transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
}
}
[aria-expanded="false"] + ul {
transform: var(--nav-list-transform, translateX(100%));
visibility: var(--nav-list-visibility, hidden);
}
Cela garantit que seules les personnes qui n'ont pas de préférence pour les animations réduites verront l'animation.
Améliorer le style de la sélection
Les utilisateurs de clavier se fient aux styles de sélection des éléments pour s'orienter et naviguer sur une page. Les styles de sélection par défaut sont préférables à l'absence de style de sélection (ce qui se produit si vous définissez outline: none), mais des styles de sélection personnalisés plus visibles améliorent l'expérience utilisateur.
Voici à quoi ressemblent les styles de sélection par défaut du lien dans Chrome 103.
Vous pouvez améliorer cela en fournissant vos propres styles dans vos propres couleurs. En utilisant :focus-visible au lieu de :focus, vous laissez le navigateur décider quand il est approprié d'afficher les styles de sélection. Les styles :focus seront visibles par tous les utilisateurs (souris, clavier et écran tactile), qu'ils en aient besoin ou non. Avec :focus-visible, le navigateur utilise des heuristiques internes pour décider s'il doit les afficher uniquement pour les utilisateurs du clavier ou pour tout le monde.
/* Remove the default :focus outline */
*:focus {
outline: none;
}
/* Show a custom outline on :focus-visible */
*:focus-visible {
outline: 2px solid var(--color-shades-dark);
outline-offset: 4px;
}
Compatibilité des navigateurs avec :focus-visible
Il existe différentes façons de mettre en évidence les éléments lorsqu'ils sont sélectionnés. Nous vous recommandons d'utiliser la propriété outline, car elle ne perturbe pas la mise en page, ce qui pourrait se produire avec border, et elle fonctionne bien avec le mode Contraste élevé sous Windows. Les propriétés qui ne fonctionnent pas bien sont background-color ou box-shadow, car elles risquent de ne pas s'afficher du tout avec des paramètres de contraste personnalisés.
Félicitations ! Vous avez créé une navigation principale accessible, adaptée aux mobiles, sémantiquement riche et à amélioration progressive.
Il y a toujours des points à améliorer, par exemple :
- Vous pouvez envisager de piéger le focus dans la navigation ou de rendre le reste de la page inerte sur les fenêtres d'affichage étroites.
- Vous pouvez ajouter un lien d'ancrage en haut de la page pour permettre aux utilisateurs du clavier d'ignorer la navigation.
Si vous vous souvenez du début de cet article, l'objectif était que la solution ne soit "ni trop simple, ni trop compliquée". C'est là que nous en sommes. Il est toutefois possible de surcharger une navigation.
Navigations et menus
Il existe une différence nette entre les navigations et les menus. Les navigations sont des collections de liens permettant de parcourir des documents associés. Les menus sont des collections d'actions à effectuer dans un document. Il peut arriver que ces tâches se chevauchent. Vous pouvez avoir une navigation qui inclut également un bouton qui effectue une action, comme l'ouverture d'une fenêtre modale, ou vous pouvez avoir un menu où une action consiste à accéder à une autre page, comme une page d'aide. Dans ce cas, il est important de ne pas mélanger les rôles ARIA, mais d'identifier l'objectif principal de votre composant et de choisir le balisage et les rôles en conséquence.
L'élément <nav> a un rôle ARIA implicite de navigation, ce qui suffit à indiquer que l'élément est une navigation. Cependant, les sites utilisent souvent menu, menubar et menuitem. Comme nous utilisons parfois ces termes de manière interchangeable, on pourrait penser qu'il est judicieux de les combiner pour améliorer l'expérience des utilisateurs de lecteurs d'écran. Avant de découvrir pourquoi ce n'est généralement pas le cas, examinons la définition officielle de ces rôles.
Le rôle de navigation
Ensemble d'éléments de navigation (généralement des liens) permettant de naviguer dans le document ou dans des documents associés.
navigation (rôle) WAI-ARIA 1.1
Rôle de menu
Un menu est souvent une liste d'actions ou de fonctions courantes que l'utilisateur peut appeler. Le rôle de menu est approprié lorsqu'une liste d'éléments de menu est présentée d'une manière semblable à un menu sur une application de bureau.
menu (role) WAI-ARIA 1.1
Le rôle menubar
Présentation d'un menu qui reste généralement visible et qui est généralement présenté horizontalement. Le rôle "menubar" permet de créer une barre de menu semblable à celles des applications de bureau Windows, Mac et Gnome. Une barre de menu est utilisée pour créer un ensemble cohérent de commandes fréquemment utilisées. Les auteurs doivent s'assurer que l'interaction avec la barre de menu est semblable à l'interaction classique avec la barre de menu dans une interface utilisateur graphique de bureau.
menubar (role) WAI-ARIA 1.1
Le rôle menuitem
Option d'un ensemble de choix contenus dans un menu ou une menubar.
menuitem (role) WAI-ARIA 1.1
La spécification est très claire ici : utilisez "navigation" pour naviguer dans le document ou les documents associés, et "menu" uniquement pour une liste d'actions ou de fonctions similaires aux menus des applications de bureau. Si vous ne créez pas le prochain Google Docs, vous n'avez probablement pas besoin des rôles de menu pour la navigation principale.
Quand un menu est-il approprié ?
L'utilisation principale des éléments de menu n'est pas la navigation, mais l'exécution d'actions. Imaginons que vous disposiez d'une liste ou d'un tableau de données et que les utilisateurs puissent effectuer certaines actions sur chaque élément de la liste. Vous pouvez ajouter un bouton à chaque ligne et afficher les actions lorsque les utilisateurs cliquent sur le bouton.
<ul>
<li>
Product 1
<button aria-expanded="false" aria-controls="options1">Edit</button>
<div role="menu" id="options1">
<button role="menuitem">
Duplicate
</button>
<button role="menuitem">
Delete
</button>
<button role="menuitem">
Disable
</button>
</div>
</li>
<li>
Product 2
...
</li>
</ul>
Implications de l'utilisation des rôles de menu
Il est très important d'utiliser ces rôles de menu à bon escient, car de nombreux problèmes peuvent survenir.
Les menus attendent une certaine structure DOM. menuitem doit être un élément enfant direct de menu. Le code suivant peut perturber le comportement sémantique :
<!-- Wrong, don't do this -->
<ul role="menu">
<li>
<a href="#" role="menuitem">Item 1</a>
</li>
</ul>
Les utilisateurs expérimentés s'attendent à ce que certains raccourcis clavier fonctionnent avec les menus et les barres de menu. D'après le guide des pratiques de création ARIA (APG), cela inclut :
- Entrée et Espace pour sélectionner des éléments de menu.
- Utilisez les touches fléchées dans toutes les directions pour passer d'un élément à l'autre.
- Les touches Début et Fin pour déplacer le curseur respectivement sur le premier ou le dernier élément.
- a-z pour déplacer la sélection vers l'élément de menu suivant dont le libellé commence par le caractère saisi.
- Esc pour fermer le menu.
Si un lecteur d'écran détecte un menu, le logiciel peut modifier automatiquement le mode de navigation, ce qui permet d'utiliser les raccourcis mentionnés précédemment. Les utilisateurs de lecteurs d'écran inexpérimentés ne pourront peut-être pas utiliser le menu, car ils ne connaissent pas ces raccourcis ni comment les utiliser.
Il en va de même pour les utilisateurs de clavier qui s'attendent à pouvoir utiliser Maj et Maj+Tabulation.
Il y a beaucoup de choses à prendre en compte lorsque vous créez des menus et des barres de menu, à commencer par l'opportunité de les utiliser. Lorsque vous créez un site Web standard, l'élément "nav" avec une liste et des liens est tout ce dont vous avez besoin. Cela inclut également les applications monopages ou les applications Web. La pile sous-jacente n'a pas d'importance. À moins que vous ne créiez quelque chose de très proche d'une application de bureau, évitez les rôles de menu.
Ressources supplémentaires
- Fixing Lists par Scott O'hara.
- Don't Use ARIA Menu Roles for Site Nav (Ne pas utiliser les rôles de menu ARIA pour la navigation sur le site) par Adrian Roselli.
- Menus & Menu Buttons par Heydon Pickering.
- WAI-ARIA menus, and why you should handle them with great care par Marco Zehe.
- Hiding content responsibly par Kitty Giraudel.
- :focus-visible Is Here par Matthias Ott.