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 la façon dont l'utilisation des attributs ARIA peut parfois faire plus de mal que de bien.

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é, et de balisage et d'information sémantique sous-jacent. Si l'implémentation est trop minimaliste, elle fonctionne pour la plupart des utilisateurs, mais l'expérience utilisateur (UX) risque de ne pas être excellente. Une conception excessive peut perturber les utilisateurs, voire les empêcher d'y accéder.

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

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'à ce que vous fournissiez juste assez d'informations, de styles et de fonctionnalités pour satisfaire la plupart des utilisateurs. Pour y parvenir, vous utilisez le principe d'amélioration progressive, qui stipule que vous commencez avec la solution la plus fondamentale et la plus robuste et que vous ajoutez progressivement des couches de fonctionnalités. Si, pour une raison quelconque, une couche ne fonctionne pas, la navigation continuera de fonctionner, car elle revient en douceur à 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 code CSS afin d'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);
}
Consultez l'Étape 1: HTML et CSS de base" sur CodePen.

Cela fonctionne bien pour la plupart des utilisateurs, quelle que soit la façon dont ils accèdent au site. La navigation est accessible à l'aide d'une souris, d'un clavier, d'un appareil tactile ou d'un lecteur d'écran, mais des améliorations peuvent être apportées. Vous pouvez améliorer l'expérience en ajoutant des fonctionnalités et des informations supplémentaires à ce modèle de base.

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 point de repère et autorisez les utilisateurs de lecteurs d'écran à accéder directement à la navigation à l'aide d'un raccourci.
  • Masquez la navigation dans les fenêtres d'affichage étroites.
  • Améliorez le style de mise au point.

Mettre en surbrillance la page active

Pour mettre en surbrillance la page active, vous pouvez ajouter un cours au lien correspondant.

<a href="/about-us" class="active-page">About us</a>

L'inconvénient de cette approche est qu'elle transmet les informations sur les liens actifs de manière purement visuelle. Un utilisateur aveugle de lecteur d'écran ne pouvait pas faire la différence entre la page active et les autres pages. Heureusement, la norme ARIA (Accessible Internet Applications) offre également un moyen de communiquer ces informations de façon 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, le lien présentant un style visuel qui représente la page actuellement affichée. [Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)

Grâce à cet attribut supplémentaire, les lecteurs d'écran énoncent désormais "page active", "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>

Par ailleurs, 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);
}
Consultez l'Étape 2: Mettez 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 utilisateur de lecteur d'écran aveugle ne peut pas obtenir ces informations aussi rapidement. Il devra peut-être parcourir toute la liste des liens. Cela ne pose peut-être 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 à l'avance que la navigation contient de nombreux liens, il peut décider d'utiliser un autre moyen de navigation plus efficace, comme la recherche sur site.
Encapsuler chaque lien dans un élément de liste (<li>) imbriqué dans une liste non ordonnée (<ul>) est un bon moyen de communiquer directement le nombre d'éléments.

<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, quatre é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 à l'ancien.

/* 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 présente 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 à l'autre.
  • Ils peuvent utiliser des raccourcis pour passer d'une liste à l'autre.
  • Le lecteur d'écran peut énoncer 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 présente les liens sous la forme d'un groupe cohérent d'éléments plutôt que d'une simple pile de liens.

Remarque importante concernant VoiceOver dans Safari : lorsque vous définissez list-style: none, vous perdez tous ces avantages. 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'un côté, la navigation reste utilisable et n'affecte que VoiceOver dans Safari. VoiceOver avec Chrome ou Firefox continue d'annoncer le nombre d'éléments, ainsi que l'utilisation d'autres lecteurs d'écran, tels que NVDA. D'un autre côté, l'information sémantique peut être très utile dans certaines situations. Pour prendre cette décision, vous devez tester la navigation avec de vrais utilisateurs de lecteurs d'écran et obtenir leurs commentaires. Si vous souhaitez que VoiceOver dans Safari se comporte comme tous les autres lecteurs d'écran, vous pouvez contourner le problème en définissant explicitement le rôle de liste ARIA dans <ul>. Cette opération rétablit le comportement antérieur à la suppression du style de la liste. Visuellement, la liste ne change pas.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Consultez la section Étape 3: Annoncer le nombre d'éléments sur CodePen.

Ajouter un point de repère

Avec peu d'efforts, vous avez apporté d'importantes améliorations aux utilisateurs de lecteurs d'écran, mais vous pouvez encore effectuer une dernière action. D'un point de vue sémantique, la navigation est toujours une simple liste de liens, et il est difficile de savoir que cette liste spécifique correspond à la navigation principale sur 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 lui et ajoute un point de repère sur la page. Les points de repère sont des régions spéciales sur la page (<header>, <footer> ou <main>, par exemple) auxquelles un lecteur d'écran peut accéder. La présence de points de repère sur une page peut s'avérer utile, 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 point à un autre en appuyant sur la touche D dans NVDA. Dans Voice Over, vous pouvez utiliser le rotor pour lister tous les points de repère de la page en appuyant sur VO+U.

Une liste de quatre points de repère: bannière, navigation, principal et informations sur le contenu.
Rotor dans VoiceOver pour lister tous les points de repère d'une page.

Cette liste comporte quatre points de repère: la bannière, qui correspond à l'élément <header>, la navigation, au <nav>, la main à l'élément <main> et les informations sur le contenu au <footer>. Cette liste ne doit pas être trop longue. Vous devez uniquement marquer les parties critiques de votre interface utilisateur comme des points de repère, comme la recherche sur site, une navigation locale ou une pagination.

Si vous disposez d'une navigation sur l'ensemble 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>. Ce n'est pas un problème, mais maintenant il y a trois points de repère de navigation qui se ressemblent tous d'un point de vue sémantique. Il est difficile de les distinguer, sauf si vous connaissez très bien la structure de la page.

Image montrant trois points de repère qui indiquent tous &quot;navigation&quot;.
Rotor dans VoiceOver indiquant trois repères de navigation sans libellé.

Pour les distinguer, vous devez les étiqueter à 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 faire référence au 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 éloquent. Omettez les expressions telles que "navigation" ou "menu", car le lecteur d'écran fournit déjà ces informations aux utilisateurs.

Points de repère
VoiceOver affichant les points de repère "Bannière", "Navigation principale", "Principale", "Navigation sur les pages", "Navigation sur la page de sélection" et "Informations sur le contenu"
Consultez la section Étape 4: Ajouter un point de repère sur CodePen.

Masquer la navigation dans les fenêtres d'affichage étroites

Personnellement, je n'aime pas vraiment masquer la navigation principale dans les fenêtres d'affichage étroites, mais si la liste de liens devient trop longue, il n'y a aucun moyen de l'éviter. Dans ce cas, au lieu de la liste, les utilisateurs voient un bouton intitulé « Menu », une icône de hamburger ou une combinaison de ces éléments. Cliquez sur le bouton pour afficher ou masquer la liste. Si vous connaissez les langages JavaScript et CSS de base, c'est une tâche réalisable. Toutefois, vous devez vous occuper de plusieurs choses 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 a du sens, même lorsque JavaScript est désactivé.
Votre navigation a d'abord besoin d'un bouton de hamburger. Vous le créez en HTML dans un élément de modèle, le clonez en JavaScript, puis l'ajoutez à la navigation.

Page affichant un bouton de hamburger.
Résultat: Au lieu des liens, la navigation affiche un bouton de hamburger dans les fenêtres d'affichage é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 dit "accessible", une alternative textuelle à l'icône de hamburger.
  3. Vous masquez le <svg> aux technologies d'assistance à l'aide de aria-hidden, car il est déjà associé à un libellé textuel fourni par aria-label.
  4. aria-controls indique à la technologie d'assistance qui prend en charge 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);
  1. Les utilisateurs ont la possibilité de fermer la navigation quand ils le souhaitent, 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 de lecteur d'écran appuie sur Tabulation après avoir cliqué sur le bouton, il s'attend à pouvoir sélectionner le premier élément de la liste. Si le bouton apparaît après la liste, ce n'est pas le cas.

Ensuite, réinitialisez le style par défaut du bouton et assurez-vous qu'il n'est visible que dans 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);
}
Consultez la section É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 d'optimiser la mise en page pour les fenêtres d'affichage étroites, tout en conservant un affichage correct sur les grands écrans.
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 dans les fenêtres d'affichage étroites en ajoutant une propriété personnalisée (—-nav-list-layout). Par défaut, la mise en page est en colonnes et s'affiche en lignes sur les grands écrans.

@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;
}

L'interface de navigation doit se présenter comme suit sur les fenêtres d'affichage étroites.

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

La liste a évidemment besoin de code CSS. Nous allons le déplacer jusqu'à l'angle supérieur, le faire remplir verticalement tout l'écran, puis appliquer une background-color et une 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 fenêtres d'affichage étroites, la liste doit ressembler davantage à une barre latérale qu'à 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 et masquez-la lorsqu'il clique à nouveau. Il est important de ne masquer que la liste et non toute la navigation, car masquer la navigation impliquerait également le masquage d'un point de 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 cette information comme condition pour afficher et masquer la liste dans 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 garantissent que les liens ne sont pas sélectionnables lorsque la navigation est masquée. Si vous utilisez opacity ou translate, le contenu est supprimé visuellement, de sorte que les liens deviennent invisibles, mais toujours accessibles à l'aide du clavier, ce qui peut être déroutant et frustrant. Si vous utilisez visibility ou display, vous le masquez visuellement et devient inaccessible, donc pour tous les utilisateurs.

Consultez l'Étape 6: Masquer la liste.

Animer la liste

Si vous vous demandez pourquoi utiliser visibility: hidden; plutôt que display: none;, vous pouvez animer la visibilité. Elle n'a que deux états, hidden et visible, mais vous pouvez la 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 remplace opacity pour créer un effet de fondu à l'ouverture et à la fermeture.

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, nous vous conseillons d'encapsuler la propriété transition dans une requête média prefers-reduced-motion, car les animations peuvent provoquer des nausées, des étourdissements 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 la préférence pour les mouvements réduits verront l'animation.

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

Améliorer le style de mise au point

Les utilisateurs du clavier s'appuient sur les styles de mise au point des éléments pour l'orientation et la navigation sur une page. Les styles de mise au point par défaut sont préférables à aucun style de mise au point (ce qui se produit si vous définissez outline: none), mais des styles de mise au point personnalisés plus clairement visibles améliorent l'expérience utilisateur.

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

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

Vous pouvez améliorer cela en utilisant vos propres styles dans vos propres couleurs. En utilisant :focus-visible au lieu de :focus, vous laissez le navigateur décider quand afficher les styles de focus. Les styles :focus seront visibles par tous (utilisateurs de la souris, du clavier et des appareils tactiles), 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;
}

Navigateurs compatibles avec :focus-visible

Navigateurs pris en charge

  • 86
  • 86
  • 85
  • 15,4

Source

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

Il existe différentes manières de mettre en avant des éléments lorsqu'ils sont sélectionnés. Nous vous recommandons d'utiliser la propriété outline, car elle n'interrompt pas la mise en page, ce qui peut se produire avec border. De plus, elle fonctionne bien avec le mode contraste élevé sous Windows. Les propriétés background-color ou box-shadow ne fonctionnent pas correctement, car elles risquent de 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 surbrillance en violet.
Consultez l'Étape 8: Améliorer les styles de focus sur CodePen.

Félicitations ! Vous avez créé une navigation principale améliorée progressivement, enrichie d'un point de vue sémantique, accessible et adaptée aux mobiles.

Il y a toujours quelque chose qui peut être amélioré, par exemple:

  • Vous pouvez piéger le curseur dans la navigation ou rendre le reste de la page inerte dans les fenêtres d'affichage étroites.
  • Vous pouvez ajouter un lien d'omission en haut de la page pour permettre aux utilisateurs du clavier d'ignorer la navigation.

Rappelez-vous comment cet article a commencé, avec pour objectif de proposer une solution "ni trop simple, ni trop compliquée", c'est là que nous en sommes maintenant. Il est toutefois possible de sur-concevoir une navigation.

Il y a une nette différence entre les navigations et les menus. Les navigations sont des collections de liens permettant de parcourir les documents associés. Les menus sont des ensembles d'actions à effectuer dans un document. Parfois, 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 un menu dans lequel une action 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 la fonction principale de votre composant, et de sélectionner le balisage et les rôles en conséquence.

L'élément <nav> dispose d'un rôle ARIA implicite de navigation, suffisant pour indiquer qu'il s'agit d'une navigation. Toutefois, les sites utilisent souvent un menu, une barre de menu et un élément de menu. Étant donné que nous utilisons parfois ces termes de manière interchangeable, il peut être 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.

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

Le 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 comme un menu dans une application de bureau.

menu (rôle) WAI-ARIA 1.1

Le rôle de la barre de menu

Une présentation d'un menu qui reste généralement visible et est généralement présenté horizontalement. Le rôle Barre de menus permet de créer une barre de menus 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 menus est semblable à l'interaction typique de celle-ci dans une interface utilisateur graphique pour ordinateur de bureau.

menubar (role) WAI-ARIA 1.1

Le rôle Menuitem

Option d'un ensemble d'options contenue dans un menu ou une barre de menu.

menuitem (role) WAI-ARIA 1.1

La spécification est très claire ici. Utilisez la navigation pour naviguer dans le document ou les documents associés et "Menu" uniquement pour une liste d'actions ou de fonctions semblables aux menus des applications de bureau. Si vous ne créez pas la prochaine version de Google Docs, vous n'aurez 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 pour effectuer des actions. Supposons que vous ayez une liste ou 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>

Implications de l'utilisation des rôles de menu

Il est vraiment important d'utiliser ces rôles de menu à bon escient, car beaucoup de choses peuvent mal tourner.

Les menus nécessitent une certaine structure DOM. menuitem doit être un élément enfant direct de menu. Le code suivant peut interrompre 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 de création ARIA (APG), ces informations incluent les éléments suivants:

  • Appuyez sur 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 Accueil et Fin permettent respectivement de placer le curseur sur le premier ou le dernier élément.
  • a-z pour sélectionner 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 changer automatiquement de mode de navigation, permettant ainsi l'utilisation des raccourcis mentionnés précédemment. Les utilisateurs inexpérimentés de lecteur d'écran peuvent ne pas pouvoir utiliser le menu, car ils ne connaissent pas ces raccourcis ou comment les utiliser.

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

Il y a beaucoup de choses à prendre en compte lorsque vous créez des menus et des barres de menu, et s'il est approprié de les utiliser en premier lieu. Lorsque vous créez un site Web standard, l'élément de navigation avec une liste et des liens est tout ce dont vous avez besoin. Cela inclut également les applications monopages (SPA) ou Web. La pile sous-jacente n'a pas d'importance. À moins que vous ne conceviez quelque chose qui est très proche d'une application de bureau, évitez les rôles de menu.

Autres ressources

Image principale de Mick Haupt