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 faire plus de mal que de bien.

Manuel Matuzović
Manuel Matuzović

Il existe de nombreuses façons différentes de créer la navigation principale d'un site Web en termes de style, de fonctionnalité, de balisage sous-jacent et d'informations sémantiques. Si l'implémentation est trop minimaliste, cela fonctionne pour la plupart des utilisateurs, mais l'expérience utilisateur (UX) risque de ne pas être excellente. Un outil trop technique peut dérouter les utilisateurs, voire les empêcher d'y accéder.

Pour la plupart des sites Web, vous souhaitez créer quelque chose qui ne soit ni trop simple, ni trop compliqué.

Bâtiment calque par calque

Dans ce tutoriel, vous allez commencer par une configuration de base, puis ajouter des fonctionnalités couche par couche jusqu'à ce que vous fournissiez suffisamment d'informations, de styles 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 commencez par la solution la plus fondamentale et la plus robuste, puis que vous ajoutez progressivement des couches de fonctionnalités. Si une couche ne fonctionne pas pour une raison quelconque, la navigation continue de fonctionner, car elle revient normalement à 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);
}
Afficher Étape 1: HTML et CSS simplifiés" sur CodePen.

Cette méthode fonctionne bien pour la plupart des utilisateurs, quelle que soit la façon dont ils accèdent au site. La navigation est accessible avec une souris, un clavier, un appareil tactile ou un lecteur d'écran, mais elle peut être améliorée. Vous pouvez améliorer votre expérience en y ajoutant des fonctionnalités et des informations supplémentaires.

Voici ce que vous pouvez faire :

  • Sélectionnez la page active.
  • Annoncez le nombre d'éléments aux utilisateurs de lecteurs d'écran.
  • Ajoutez un point de 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éliorez le style de mise au point.

Mettre la page active en surbrillance

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>

Le problème de cette approche est qu'elle transmet l'information dont le lien est actif purement visuel. Un utilisateur aveugle d'un lecteur d'écran ne sait pas faire la différence entre la page active et les autres pages. Heureusement, la norme ARIA (Accessible Rich Internet Applications) offre également un moyen de communiquer ces informations sémantiquement. Utilisez l'attribut et la valeur aria-current=&quot;page&quot; au lieu d'une classe.

<ph type="x-smartling-placeholder">
</ph> 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 au sein d'un ensemble de liens de pagination. 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>

Résultat : vous pouvez utiliser l'attribut pour sélectionner le lien actif dans 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: Mettre en surbrillance la page active sur CodePen.

Annoncer le nombre d'éléments

En regardant la navigation, les utilisateurs voyants peuvent dire qu'elle ne contient que quatre liens. Un utilisateur de lecteur d'écran aveugle ne peut pas obtenir ces informations aussi rapidement. Ils devront peut-être parcourir toute la liste des liens. Ce n'est peut-être pas un 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 un moyen de navigation différent et 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 un message du type "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'é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 é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 affiche les liens sous la forme d'un groupe cohérent d'éléments, et non sous la forme d'une simple pile de liens.

Remarque importante concernant VoiceOver dans Safari : 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 des listes lorsqu'elles ne ressemblent pas à des listes. Selon la complexité de votre navigation, le problème peut ou non être affecté. D'une part, 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 les autres lecteurs d'écran, comme NVDA. D'un autre côté, les informations sémantiques pourraient être très utiles dans certaines situations. Pour prendre cette décision, vous devez tester la navigation auprès d'utilisateurs réels du lecteur d'écran et obtenir leurs commentaires. Si vous souhaitez que VoiceOver dans Safari fonctionne 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>. Cette opération rétablit le comportement de l'état avant la suppression du style de la liste. Visuellement, la liste n'a pas changé.

<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 encore une chose que vous pouvez faire. La navigation est sémantiquement juste 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. Lorsque l'utilisateur interagit avec un lecteur d'écran, un lecteur d'écran annonce par exemple "navigation" et ajoute un point de repère sur 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 point de repère à un point de repère 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.

<ph type="x-smartling-placeholder">
</ph> Une liste de quatre points de repère: bannière, navigation, principal et informations sur le contenu.
Rotor dans VoiceOver listant tous les points de repère d'une page

Dans cette liste, quatre points de repère s'affichent: la bannière (l'élément <header>), la navigation (<nav>), l'élément main (<main>), et les informations de contenu, le <footer>. Cette liste ne doit pas être trop longue. Vous ne devez marquer que les parties critiques de votre interface utilisateur comme des points de repère, comme la recherche sur le 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 il y a maintenant 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.

<ph type="x-smartling-placeholder">
</ph> Image montrant trois points de repère indiquant tous &quot;navigation&quot;.
Le rotor de VoiceOver indique trois repères de navigation sans libellé.

Pour les distinguer, vous devez les étiqueter à 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à 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>

Une étiquette concise est suffisante. Soyez trop verbeux. Omettre les expressions telles que "navigation" ou "menu" car le lecteur d'écran fournit déjà aux utilisateurs ces informations.

<ph type="x-smartling-placeholder">
</ph> Points de repère
VoiceOver listant les repères "banner", "main navigation", "main", "page navigation", "select page navigation" et "informations sur le contenu".
Consultez l'É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 trop masquer la navigation principale dans les fenêtres d'affichage étroites, mais si la liste des liens devient trop longue, il n'y a aucun moyen de contourner ce problème. Dans ce cas, au lieu de la liste, les utilisateurs voient un bouton intitulé « Menu » ou une icône de hamburger ou une combinaison des deux. Cliquez sur ce bouton pour afficher et masquer la liste. Si vous connaissez les bases de JavaScript et de CSS, c'est une tâche réalisable, mais 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 avec le clavier.
  • La navigation doit indiquer s'il est visible ou non.

Ajouter un bouton de hamburger

Étant donné que 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é.
La première chose dont vous avez besoin pour la navigation est un bouton en forme de hamburger. Vous allez la créer en HTML dans un élément de modèle, le cloner en JavaScript, puis l'ajouter à la navigation.

<ph type="x-smartling-placeholder">
</ph> Page affichant un bouton en forme de hamburger.
Résultat: au lieu de liens, la navigation affiche un bouton en forme de hamburger sur 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 appelé "accessible", qui remplace l'icône en forme de hamburger sous forme de texte.
  3. Vous masquez <svg> des 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) qui est 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. Les utilisateurs peuvent facilement 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 d'un clavier ou d'un 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. Ce ne serait pas le cas si le bouton s'affiche après la liste.

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 l'Étape 5: Ajouter un bouton en forme de hamburger sur CodePen.

Masquer la liste

Avant de masquer la liste, positionnez et mettez en forme la navigation et la liste afin d'optimiser la mise en page pour les fenêtres d'affichage étroites, tout en conservant un aspect optimal 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;
}

Ensuite, modifiez la mise en page sur 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 passe 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;
}

Sur les fenêtres d'affichage étroites, la navigation doit ressembler à ceci.

<ph type="x-smartling-placeholder">
</ph> Page affichant la liste de navigation et le bouton en forme de hamburger.
Le bouton en forme de hamburger et la liste sont placés dans l'angle supérieur de la fenêtre d'affichage.

La liste a évidemment besoin d'un peu de code CSS. Nous allons la déplacer jusqu'à l'angle supérieur, faire en sorte qu'elle remplisse tout l'écran verticalement, et appliquer background-color et 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 se présenter comme suit : elle ressemble davantage à une barre latérale qu'à une simple liste.

La liste de navigation s&#39;ouvre.

Enfin, masquez la liste, n'affichez-la que lorsque l'utilisateur clique une fois sur le bouton et masquez-la lorsqu'il clique de nouveau. Il est important de masquer uniquement la liste et non l'intégralité de la navigation, car masquer la navigation signifierait également masquer 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 ces informations 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é comme 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 peuvent pas être sélectionnés lorsque la navigation est masquée. L'utilisation de opacity ou translate entraîne la suppression visuelle du contenu, de sorte que les liens restent invisibles, mais restent accessibles à l'aide du clavier, ce qui peut être source de confusion et de frustration. Si vous utilisez visibility ou display, il est masqué visuellement et inaccessible, et donc pour tous les utilisateurs.

Consultez l'Étape 6: Masquer la liste.

Animer la liste

Vous vous demandez pourquoi utiliser visibility: hidden; plutôt que display: none;, car vous pouvez animer la visibilité. Il n'a que deux états, hidden et visible, mais vous pouvez le combiner à 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.

La CSS suivante effectue une transition opacity pour créer un effet de fondu en entrée et en 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 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 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 de clavier s'appuient sur les styles de focus des éléments pour l'orientation et la navigation sur une page. Les styles de focus par défaut sont préférables à aucun style de focus (ce qui se produit si vous définissez outline: none), mais les styles de ciblage personnalisés plus clairement visibles améliorent l'expérience utilisateur.

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 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 focus. Les styles :focus seront visibles par tous les utilisateurs (souris, clavier et 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

  • Chrome: 86 <ph type="x-smartling-placeholder">
  • Edge: 86 <ph type="x-smartling-placeholder">
  • Firefox: 85 <ph type="x-smartling-placeholder">
  • Safari: 15.4. <ph type="x-smartling-placeholder">

Source

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

Il existe différentes manières de mettre en surbrillance des éléments lorsqu'ils sont sélectionnés. Nous vous recommandons d'utiliser la propriété outline, car elle n'affecte pas la mise en page, ce qui peut se produire avec border. De plus, elle fonctionne bien avec le mode de contraste élevé sous Windows. Les propriétés background-color ou box-shadow ne fonctionnent pas bien, car elles risquent de ne pas s'afficher du tout avec des paramètres de contraste personnalisés.

Un site avec un arrière-plan sombre et le focus mis en évidence en violet.
Consultez l'Étape 8: Améliorer les styles de focus dans CodePen.

Félicitations ! Vous avez créé une navigation principale progressivement enrichie, 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 "Ignorer" en haut de la page pour permettre aux utilisateurs de clavier d'ignorer 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 nette différence entre la navigation 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 comprend également un bouton qui effectue une action, comme ouvrir une fenêtre modale, ou vous pouvez avoir 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 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 est suffisant pour indiquer qu'il s'agit d'une navigation. Toutefois, vous voyez souvent que les sites utilisent également 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 naviguer dans 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 la barre de menu

Présentation d'un menu qui reste généralement visible et qui est généralement présenté horizontalement. Le rôle de barre de menus est utilisé pour créer une barre de menus similaire à celles que l’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 qui s'affiche habituellement dans l'interface utilisateur graphique d'un ordinateur de bureau.

menubar (rôle) WAI-ARIA 1.1
.

Rôle menuitem

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

menuitem (rôle) WAI-ARIA 1.1
.

Les spécifications sont très claires 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 similaires 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 le menu de navigation principal.

Dans quels cas un menu est-il approprié ?

L'utilisation principale des éléments de menu n'est pas la navigation, mais d'effectuer des 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>

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 se passer.

Les menus nécessitent une certaine structure DOM. menuitem doit être un élément enfant direct de menu. Le code suivant pourrait rompre 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 menus. D'après le Guide des pratiques de création ARIA (APG), ce guide inclut les éléments suivants:

  • Appuyez sur 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 placer le curseur sur le premier ou le dernier élément, respectivement.
  • a-z pour passer à l'élément de menu suivant dont le libellé commence par le caractère saisi.
  • Appuyez sur Échap pour fermer le menu.

Si un lecteur d'écran détecte un menu, le logiciel peut modifier automatiquement le mode de navigation, permettant ainsi 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 claviers 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 vous devez décider s'il est approprié de les utiliser en premier lieu. 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. À moins que vous ne créiez quelque chose qui s'apparente à une application de bureau, évitez les rôles de menu.

Autres ressources

Image principale de Mick Haupt