Créer la navigation principale d’un site Web

Ce tutoriel explique comment créer une navigation principale accessible sur un site Web. Vous découvrirez le HTML sémantique, l'accessibilité et comment l'utilisation d'attributs ARIA peut parfois être contre-productive.

Manuel Matuzović
Manuel Matuzović

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 et d'informations sémantiques sous-jacentes. Si l'implémentation est trop minimaliste, elle fonctionne pour la plupart des utilisateurs, mais l'expérience utilisateur (UX) peut ne pas être optimale. Un outil trop technique peut dérouter les utilisateurs, voire les empêcher d'y accéder.

Pour la plupart des sites Web, vous devez créer quelque chose qui n'est ni trop simple, ni trop compliqué.

Bâtiment calque par calque

Dans ce tutoriel, vous commencez par une configuration de base et ajoutez des fonctionnalités couche par couche jusqu'à ce que vous fournissiez 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 stipule que vous devez 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 continue de fonctionner, car elle revient à 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.

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* 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);
}
Affichez Étape 1 : HTML et CSS de base sur CodePen.

Cette méthode 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 il y a place à amélioration. 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 :

  • Sélectionnez la page active.
  • Annoncer le nombre d'éléments aux utilisateurs de lecteurs d'écran
  • Ajoutez un repère et autorisez les utilisateurs de lecteurs d'écran à accéder directement à la navigation à l'aide d'un raccourci.
  • Masquer la navigation sur les vues d'écran étroites.
  • Amélioration du style de sélection.

Mettre en surbrillance la page active

Pour mettre en surbrillance 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 utilisant un lecteur d'écran ne pouvait pas faire la différence entre la page active et les autres pages. Heureusement, la norme Accessible Rich Internet Applications (ARIA) permet également de communiquer ces informations de manière sémantique. Utilisez l'attribut et la valeur aria-current=&quot;page&quot; 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);
}
Affichez Étape 2: Mettre en surbrillance la page active sur CodePen.

Annoncer le nombre d'éléments

En regardant la navigation, les utilisateurs voyants peuvent voir qu'elle ne contient que quatre liens. Un lecteur d'écran aveugle ne peut pas obtenir ces informations aussi rapidement. Il peut être amené à parcourir toute la liste des liens. Cela peut ne pas poser de problème si la liste est courte, comme dans cet exemple, mais si elle contient 40 liens, cette tâche peut s'avérer fastidieuse. Si un utilisateur de lecteur d'écran sait à l'avance que la navigation contient de nombreux liens, il peut décider d'utiliser une autre méthode de navigation plus efficace, comme la recherche sur le site.
Un bon moyen de communiquer le nombre d'éléments à l'avance consiste à encapsuler chaque lien dans un élément de liste (<li>), imbriqué dans une liste non trié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 à celui d'avant.

/* 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'articles 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'indice 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érents au lieu 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 ou non être un problème. D'une part, la navigation reste utilisable et 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, comme 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 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>. Le comportement est alors rétabli à l'état antérieur à la suppression du style de la liste. Visuellement, la liste reste la même.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Voir Étape 3: Annonce du nombre d'éléments sur CodePen

Ajouter un point de repère

Avec peu d'effort, vous avez apporté d'importantes améliorations pour les utilisateurs de lecteurs d'écran, mais il reste une dernière chose que vous pouvez faire. D'un point de vue sémantique, la navigation est toujours simplement une liste de liens et il est difficile de dire 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. Par exemple, un lecteur d'écran annonce "navigation" lorsque l'utilisateur interagit avec lui et ajoute un repère à la page. Les points de repère sont des zones spéciales sur la page, comme <header>, <footer> ou <main>, auxquelles un lecteur d'écran peut accéder. La présence de points de repère sur une page peut être utile, car cela permet aux utilisateurs de lecteurs d'écran d'accéder directement à des 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 afficher tous les repères de la page en appuyant sur VO+U.

Liste de quatre repères : bannière, navigation, principal, informations sur le contenu.
Rotors dans VoiceOver qui liste tous les repères d'une page.

Dans cette liste, quatre repères s'affichent: la bannière (l'élément <header>), la navigation (<nav>), l'élément main (<main>) et les informations de contenu (<footer>). Cette liste ne doit pas être trop longue. Vous ne devez marquer que les éléments essentiels de votre interface utilisateur comme des repères, comme la recherche sur le site, une navigation locale ou une pagination.

Si vous disposez d'une navigation à l'échelle du site, d'une navigation locale pour la page et d'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, sauf si vous connaissez très bien la structure de la page.

Image montrant trois repères indiquant tous &quot;navigation&quot;.
Le rotor de VoiceOver affichant trois repères de navigation non libellés.

Pour les distinguer, vous devez les libeller à l'aide de aria-labelledby ou de 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à 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 est suffisant. Ne vous égarez pas dans des descriptions trop longues. Omettre des expressions telles que "navigation" ou "menu", car le lecteur d'écran fournit déjà ces informations aux utilisateurs.

Points de repère
Voix off énumérant les repères "bannière", "navigation principale", "principal", "navigation de page", "navigation de page sélectionnée" et "informations sur le contenu".
Consultez Étape 4: Ajouter un repère sur CodePen.

Masquer la navigation sur les vues d'écran étroites

Personnellement, je ne suis pas très fan de la dissimulation de la navigation principale sur les vues d'écran é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 et masquer la liste. Si vous connaissez les bases de JavaScript et de CSS, cette tâche est réalisable. Toutefois, vous devez prendre en compte 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 s'il est visible ou non.

Ajouter un bouton hamburger

Étant donné que vous suivez le principe d'amélioration progressive, vous devez vous assurer que votre navigation fonctionne toujours et qu'elle a du sens, 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, le clonez en JavaScript et l'ajoutez à la navigation.

Page affichant un bouton en forme de hamburger.
Résultat : Au lieu de liens, la navigation affiche un bouton hamburger sur les vues d'écran étroites.
<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>
  1. L'attribut aria-expanded indique au logiciel de lecteur d'écran si l'élément contrôlé par le bouton est développé ou non.
  2. aria-label attribue au bouton un nom accessible, un texte alternatif pour l'icône hamburger.
  3. Vous masquez le <svg> de la technologie d'assistance à l'aide de aria-hidden, car il dispose déjà d'un libellé textuel fourni par aria-label.
  4. aria-controls indique à la technologie d'assistance compatible avec l'attribut (par exemple, JAWS) l'élément contrôlé par le bouton.
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);
  1. Il est pratique pour les utilisateurs de pouvoir fermer la navigation à tout moment, par exemple en appuyant sur la touche Échap.
  2. Il est important d'utiliser insertBefore au lieu de appendChild, car le bouton doit être le premier élément de votre navigation. Si un utilisateur de clavier ou d'un lecteur d'écran appuie sur la touche Tabulation après avoir cliqué sur le bouton, il s'attend à ce que le premier élément de la liste soit sélectionné. Ce ne serait pas le cas si le bouton se trouvait après la liste.

Ensuite, vous réinitialisez le style par défaut du bouton et vous vous assurez qu'il n'est visible que dans les vues d'écran étroites.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
Affichez Étape 5: Ajouter un bouton hamburger sur CodePen.

Masquer la liste

Avant de masquer la liste, positionnez et stylisez la navigation et la liste afin que la mise en page soit optimisée pour les vues d'écran étroites, mais qu'elle reste agréable sur les grands écrans.
Tout d'abord, supprimez la <nav> du flux naturel de la page et placez-la 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;
}

Modifiez ensuite la mise en page dans les fenêtres d'affichage étroites en ajoutant une propriété personnalisée (—-nav-list-layout). La mise en page est en colonnes par défaut et passe en lignes 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 doit se présenter comme suit sur les vues d'affichage étroites.

Page affichant la liste de navigation et le bouton hamburger.
Le bouton hamburger et la liste sont placés dans l'angle supérieur de la fenêtre d'affichage.

La liste a évidemment besoin de CSS. Nous allons le déplacer en haut à droite, le faire remplir tout l'écran verticalement, puis 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;
}

Sur les vues d'écran étroites, la liste doit se présenter comme ceci, plus comme une barre latérale que comme une simple liste.

La liste de navigation s&#39;ouvre.

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.

Vous avez précédemment 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é comme visibility: hidden ou display: none au lieu de opacity: 0 ou translateX(100%) pour masquer la liste. Ces propriétés garantissent que les liens ne sont pas sélectionnables lorsque la navigation est masquée. L'utilisation de opacity ou translate supprime visuellement le contenu, ce qui rend les liens invisibles, mais toujours accessibles via le clavier. Cela peut être déroutant et frustrant. Si vous utilisez visibility ou display, il est masqué visuellement et inaccessible, et donc pour tous les utilisateurs.

Affichez Étape 6: Masquer la liste.

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é. Elle n'a que deux états, hidden et visible, mais vous pouvez la combiner avec une autre propriété telle que transform ou opacity pour créer un effet de diapositive ou de fondu. Cela ne fonctionnerait pas avec display: none, car la propriété display n'est pas animatable.

Les transitions CSS suivantes opacity permettent de créer un effet de fondu.

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 préférez animer des mouvements, vous devriez envisager d'encapsuler la propriété transition dans une requête média prefers-reduce-motion, car les animations peuvent déclencher 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);
}

Ainsi, seules les personnes qui n'ont pas de préférence pour la réduction du mouvement verront l'animation.

Consultez l'Étape 7: Animer la liste sur CodePen.

Améliorer le style de la sélection

Les utilisateurs de clavier s'appuient sur les styles de sélection des éléments pour s'orienter et naviguer sur une page. Les styles de focus par défaut sont préférables à l'absence de style de focus (ce qui se produit si vous définissez outline: none), mais l'expérience utilisateur est améliorée si les styles de focus personnalisés sont plus visibles.

Voici à quoi ressemblent les styles de focus par défaut sur le lien dans Chrome 103.

Contour bleu de 2 pixels autour d&#39;un lien sélectionné dans Chrome 103

Vous pouvez améliorer ce point 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 focus. Les styles :focus sont visibles par tous les utilisateurs, qu'ils utilisent la souris, le clavier ou l'écran tactile, qu'ils en aient besoin ou non. Avec :focus-visible, le navigateur utilise des heuristiques internes pour décider de les afficher uniquement aux utilisateurs de clavier ou à tous les utilisateurs.

/* 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

Navigateurs pris en charge

  • Chrome : 86.
  • Edge : 86.
  • Firefox: 85
  • Safari: 15.4.

Source

Contour sombre clairement visible de 2 px avec un espacement à l&#39;intérieur.

Il existe différentes façons de mettre en surbrillance des éléments lorsqu'ils sont sélectionnés. L'utilisation de la propriété outline est recommandée, car elle ne casse pas la mise en page, ce qui peut se produire avec border, et elle fonctionne bien avec le mode haute intensité sur Windows. Les propriétés qui ne fonctionnent pas bien sont background-color ou box-shadow, car elles peuvent ne pas s'afficher du tout avec des paramètres de contraste personnalisés.

Site avec un arrière-plan sombre et l&#39;élément mis en avant en violet.
Consultez l'Étape 8: Améliorer les styles de focus dans CodePen.

Félicitations ! Vous avez créé une navigation principale progressive, sémantiquement riche, accessible et adaptée aux mobiles.

Il y a toujours quelque chose à améliorer, par exemple :

  • Vous pouvez placer le curseur dans la zone de navigation ou rendre le reste de la page inerte dans les fenêtres d'affichage étroites.
  • Vous pouvez ajouter un lien d'ancrage en haut de la page pour permettre aux utilisateurs de clavier de passer la navigation.

Rappelez-vous les débuts de cet article, dans le but que la solution ne soit ni trop simple, ni trop compliquée. Voilà où nous en sommes maintenant. Il est toutefois possible de sur-concevoir une navigation.

Il existe une différence claire entre les navigations et les menus. Les navigations sont des collections de liens permettant de naviguer dans les documents associés. Les menus sont des collections d'actions à effectuer dans un document. Parfois, ces tâches se chevauchent. Une navigation peut également inclure un bouton qui effectue une action, comme l'ouverture d'une fenêtre modale. Un menu peut également comporter une action qui permet d'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, puis de choisir la balise et les rôles en conséquence.

L'élément <nav> a un rôle ARIA implicite de navigation, ce qui est suffisant pour indiquer qu'il s'agit d'un élément de navigation. Toutefois, vous constatez souvent que les sites utilisent également les rôles menu, menubar et menuitem. Nous utilisons parfois ces termes de manière interchangeable, pensant que les combiner pour améliorer l'expérience des utilisateurs de lecteurs d'écran pourrait être judicieux. Avant de découvrir pourquoi ce n'est généralement pas le cas, examinons la définition officielle de ces rôles.

Rôle de navigation

Ensemble d'éléments de navigation (généralement des liens) permettant de parcourir le document ou les 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 convient lorsqu'une liste d'éléments de menu est présentée de la même manière qu'un menu dans une application de bureau.

menu (rôle) WAI-ARIA 1.1

Rôle de barre de menu

Présentation d'un menu qui reste généralement visible et est généralement présenté horizontalement. Le rôle de barre de menu permet de créer une barre de menu semblable à celles que l&#39;on trouve dans les applications de bureau Windows, Mac et Gnome. Une barre de menu permet de 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 à celle d'une interface utilisateur graphique classique sur ordinateur.

menubar (rôle) WAI-ARIA 1.1

Rôle menuitem

Option d'un ensemble de choix contenu dans un menu ou une barre de menu.

menuitem (rôle) WAI-ARIA 1.1

Les spécifications sont très claires à ce sujet. Utilisez la navigation pour parcourir le document ou les documents associés, et le menu uniquement pour une liste d'actions ou de fonctions semblables aux menus des applications pour ordinateur. Si vous ne créez pas la prochaine version de Google Docs, vous n&#39;avez probablement pas besoin de l&#39;un des rôles de menu pour la navigation principale.

Dans quel cas 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 dessus.

<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>

Conséquences de l'utilisation de rôles de menu

Il est très important d&#39;utiliser ces rôles de menu à bon escient, car de nombreux problèmes peuvent survenir.

Les menus s&#39;attendent à une certaine structure DOM. menuitem doit être un élément enfant direct de menu. Le code suivant peut endommager le comportement sémantique :

 <!-- Wrong, don't do this -->
<ul role="menu">
  <li>
    <a href="#" role="menuitem">Item 1</a>
  </li>
</ul>

Les utilisateurs avertis s'attendent à ce que certains raccourcis clavier fonctionnent avec les menus et les barres de menu. D'après le Guide des pratiques d'écriture ARIA (APG), cela inclut:

  • Utilisez les touches 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 focus respectivement sur le premier ou le dernier élément.
  • a-z pour déplacer le focus sur l'élément de menu suivant dont le libellé commence par le caractère saisi.
  • Échap 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 inexpérimentés de lecteurs d'écran peuvent ne pas être en mesure d'utiliser le menu parce qu'ils ne connaissent pas ces raccourcis ou ne savent pas comment les utiliser.

Il en va de même pour les utilisateurs de clavier qui pourraient s'attendre à pouvoir utiliser Maj et Maj+Tabulation.

De nombreux éléments doivent être pris en compte lorsque vous créez des menus et des barres de menu. La première question à vous poser est de savoir s'il est approprié de les utiliser. Lorsque vous créez un site Web classique, l'élément de navigation avec une liste et des liens suffit. Cela inclut également les applications monopages (SPA) ou les applications Web. La pile sous-jacente n'a pas d'importance. Sauf si vous créez quelque chose qui ressemble beaucoup à une application de bureau, évitez les rôles de menu.

Autres ressources

Image principale par Mick Haupt