Fermer

septembre 4, 2022

Le parcours d’accessibilité et de convivialité de la navigation principale de Drupal

Le parcours d’accessibilité et de convivialité de la navigation principale de Drupal


La navigation principale d’un site Web est essentielle à sa convivialité et à son accessibilité. Cependant, les systèmes de navigation sont trompeusement compliqués. Tous les sites Web, sauf les plus simples, doivent faire face à cela.

Avec la version 9.4, Drupal a un tout nouveau thème par défaut appelé Olivero. Étant la valeur par défaut, nous savions que son système de navigation serait utilisé par des centaines de millions (voire des milliards) d’utilisateurs tout au long de sa vie. Et de toutes les choses dont nous sommes fiers avec le nouveau thème de Drupal, le système de navigation est en tête de liste. Une énorme quantité de tests, de corrections de bugs et de soins y ont été consacrés.

Utilisable, Accessible, Robuste, Et Belle

Lorsque nous avons commencé à créer le thème, nous savions qu’il devait être utilisable, accessible, robuste et beau. Tous ces objectifs posent des défis importants.

Pour la convivialité, nous voulions inclure des menus déroulants de navigation de second niveau similaires à de nombreux sites sur Internet. Ces menus déroulants de navigation de deuxième niveau doivent s’ouvrir au survol, au clic et au toucher.

L’accessibilité est une porte principale de Drupal. Nous savions qu’il devait respecter ou dépasser les normes WCAG 2.1 AA. Plus que Rencontre les normes, nous voulons que notre thème soit un plaisir à naviguer pour ceux qui ont besoin d’utiliser la technologie d’assistance.

Et, comme nous ne contrôlons pas le contenu, le système de menus devait être très robuste. Nous ne savons pas si les éditeurs de contenu entreront un article ou des centaines ! Nous n’avons aucun contrôle sur la longueur du texte. Nous prenons également en charge l’internationalisation, qui inclut la prise en charge des langues s’écrivant de droite à gauche telles que l’arabe.

En plus de cette fonctionnalité, le menu devait également être beau. Nos concepteurs ont fait un travail incroyable en le simulant, puis nous avons intégré quelques transitions CSS de base pour ajouter un léger fondu enchaîné, une animation transformée verticalement.

Le menu d’Olivero commence par un standard <nav> élément. Nous ajoutons un aria-labelledby attribut pointant vers l’ID d’un visuel masqué (mais accessible aux lecteurs d’écran) h2 élément. Cela communique le nom de navigation aux personnes utilisant des lecteurs d’écran afin qu’elles puissent différencier les différents éléments de navigation. Il permet également aux utilisateurs de retrouver ce menu s’ils naviguent par rubriques.

Les éléments de menu reposent sur une version modifiée modèle de divulgation de lien lors de l’utilisation d’hyperliens comme élément de navigation de niveau supérieur.

Noter: Drupal peut également utiliser un <button> élément comme élément de niveau supérieur.

Ce modèle injecte un <button> élément après le lien hypertexte. Dans Olivero, nous stylisons le bouton avec une icône « chevron vers le bas ».

Menu affichant un lien hypertexte avec un élément de bouton adjacent, avec un menu déroulant en dessous
Modèle de divulgation de lien (Grand aperçu)

Le bouton a aria-controls (mappé à l’ID de l’imbriquée <ul>) et aria-expanded attributs initialisés avec JavaScript. Si le site est chargé sans JavaScript, les boutons deviennent purement de présentation.

Ce bouton contient du texte masqué visuellement avec le texte de l’élément de menu, suivi de « sous-navigation ». C’est ainsi que les personnes qui tabulent entre les contrôles de formulaire peuvent comprendre quel sous-menu le bouton contrôle.

<nav aria-labelledby="block-olivero-main-menu-menu">
  <h2 class="visually-hidden" id="block-olivero-main-menu-menu">Main navigation</h2>
  <ul>
    <li>
      <a href="https://smashingmagazine.com/">Webforms</a>
      <button aria-controls="primary-menu-item-12" aria-expanded="false">
        <span class="visually-hidden">Webforms sub-navigation</span>
      </button>
      <ul id="primary-menu-item-12">
        <!-- Submenu items -->
      </ul>
    </li>
    <!-- More top-level navigation items here. -->
  </ul>
</nav>
Plus après saut! Continuez à lire ci-dessous ↓

Les sous-menus s’ouvrent au survol, au clic et au toucher. Cependant, nous devons nous assurer que ces événements ne se déclenchent pas simultanément (comme ils peuvent le faire sur les appareils tactiles) car si le menu s’ouvre et se ferme instantanément, il semblera que rien ne s’est passé ! Nous devons également envisager des technologies d’assistance telles que des outils de balayage ponctuel qui peuvent déclencher les deux événements en succession rapide.

Outil d’analyse de pointeur MacOS en action (accéléré).

Pour tenir compte de tout cela, nous écoutons un touchstart événement et, s’il est présent, ignorez l’événement mouseover traitement des événements. Si et quand le mouseover processus événementiels, nous désactivons le click événement de faire quoi que ce soit pendant une demi-seconde. Et enfin, lorsque l’événement click est traité, nous affichons le sous-menu. La logique devient un peu compliquée, mais elle est utilisable avec n’importe quelle technologie d’assistance.

Les sous-menus doivent se fermer lorsque certaines conditions sont remplies :

  • Si la touche Échap est enfoncée, le sous-menu se ferme et le focus revient à l’élément parent.
  • Si un mouseout événement se produit, le sous-menu se ferme sauf si focus est contenu dans le sous-menu.
  • De même, les sous-menus se fermeront à la blur événement pour s’assurer que les sous-menus ne peuvent pas se masquer les uns les autres (et potentiellement violer le critère de réussite visible de la mise au point WCAG 2.4.7).

Étant donné que le thème ne peut pas contrôler le nombre d’éléments de menu saisis par l’utilisateur, nous devons en accepter un nombre illimité. Nous avons construit une option pour activer le menu mobile (qui peut contenir des éléments illimités) à toutes les largeurs d’écran. Mais il y a toujours le cas limite où il peut y avoir suffisamment d’éléments à des largeurs moyennes pour déclencher le menu pour envelopper ou déborder.

Menu enveloppé avec trop d'éléments
Le menu est renvoyé à la ligne car il contient trop d’éléments dans une fenêtre d’affichage étroite. (Grand aperçu)

Pour s’adapter à cela, nous passons au menu mobile lorsque le menu principal manque d’espace. Pour ce faire, nous définissons un observateur de redimensionnement pour déclencher une vérification pour voir si le texte est enveloppé. Si c’est le cas, nous activons le menu mobile et rappelons quand revenir à la version de bureau (si la fenêtre d’affichage est agrandie).

const navMenu = document.querySelector('.primary-nav');
const navItem = navMenu.querySelector('.primary-nav__menu-item');

function checkIfDesktopNavigationWraps() {
  if (isDesktopNav() && navMenu.height > navItem.clientHeight) {
    enableMobileNav(); // Enable the mobile navigation.
    // Remember when to switch back to desktop navigation.
    const navMediaQuery = window.matchMedia(`(max-width: ${window.innerWidth + 15}px)`);
    navMediaQuery.addEventListener('change', () => {
      // Double check to see if the navigation is wrapping to prevent edge
      // cases where the mobile menu should still be enabled.
      if (navMenu.clientHeight > navItem.clientHeight) {
        disableMobileNav(navMenu, navItem);
      }
    }, { once: true });
  }
}

const resizeObserver = new ResizeObserver(checkIfDesktopNavigationWraps);
resizeObserver.observe(navMenu);
Une capture d'écran avec un menu mobile activé
Beaucoup mieux. Le menu mobile est maintenant activé car la navigation sur le bureau ne pouvait pas prendre en charge tous les éléments du menu. (Grand aperçu)

Le menu d’Olivero est fixé en haut de la fenêtre. Les menus fixes peuvent créer un problème si la fenêtre d’affichage est plus courte que le sous-menu le plus long – l’utilisateur ne pourra jamais faire défiler pour accéder aux éléments à la fin. Cette incapacité à accéder aux éléments à la fin du menu crée un autre échec de WCAG 2.4.7 Mise au point visible.

Une capture d'écran où les éléments de menu longs sont inaccessibles sous la fenêtre
Avec un en-tête fixe et une fenêtre d’affichage courte, les éléments de menu longs ne sont pas accessibles par défilement ou tabulation. (Grand aperçu)

Nous résolvons cela en calculant la hauteur de l’en-tête et en définissant max-height et overflow: auto dans le sous-menu.

.submenu {
  max-height: calc(100vh - var(--header-height));
  overflow: auto;
}

Avec ces styles en place, le menu ne dépassera jamais la hauteur de la fenêtre d’affichage et le navigateur rendra le sous-menu déroulant uniquement si nécessaire. Si l’utilisateur tabule jusqu’au bas du sous-menu, le navigateur fera automatiquement défiler le contenu dans la vue.

Une capture d'écran où le sous-menu a une barre de défilement
Avec les styles appliqués, le sous-menu obtient une barre de défilement si le contenu est plus grand que la hauteur de la fenêtre. (Grand aperçu)

Prise en charge non-JavaScript

Étant donné que Drupal rend son balisage sur le serveur, nous avons la possibilité de prendre en charge les appareils sur lesquels JavaScript est désactivé. Pour ce faire, nous permettons :hover et :focus-within sur l’élément de menu parent.

body:not(.js) .menu-item:is(:hover, :focus-visible) .menu-level-2 {
  visibility: visible;
}

Le menu mobile d’Olivero fonctionne comme vous l’attendez. Il ne réagit pas aux survols, mais les attributs aria restent les mêmes.

La navigation mobile d'Olivero
(Grand aperçu)

La navigation mobile est activée par un <button> élément caché à la largeur du bureau. Ce bouton contient également aria-expanded et aria-controls éléments avec les valeurs appropriées.

Cliquer sur le bouton ouvre le menu, et vous pouvez fermer le menu en cliquant (ou en appuyant) en dehors du menu. De plus, le Échapper fermera le menu et remettra le focus sur le bouton du menu mobile.

Gestion du focus dans le menu

Le menu mobile d’Olivero se superpose au contenu de la page. Cela peut créer un problème d’accessibilité si le contenu masqué par le menu devient prioritaire.

Pour contourner ce problème, nous créons un « piège de mise au point » dans le menu et son bouton de fermeture. Cela garantit que si un utilisateur navigue sur le site via le clavier, il ne peut pas se concentrer en dehors du menu.

Nous avons rencontré une situation réelle où l’utilisateur a saisi un lien d’ancrage dans le menu. Une fois cliqué, le site défilerait jusqu’à la page, mais le menu serait toujours ouvert.

Pour résoudre ce problème, nous ajoutons du JavaScript qui ferme la navigation mobile si le lien cible est une ancre.

// If hyperlink links to an anchor in the current page, close the mobile menu after click.
navWrapper.addEventListener('click', (e) => {
  if (e.target.matches(`[href*="${window.location.pathname}#"], [href^="#"]`)) {
    closeNavigation();
  }
});

Pour prendre en charge le menu mobile sans JavaScript, nous devons afficher le menu sans avoir à appuyer sur le bouton d’ouverture du menu (que nous cachons car il ne fonctionne pas sans JavaScript).

Pour éviter un clignotement du menu non-JavaScript lors du chargement de la page, nous avons inclus la feuille de style non-JavaScript dans un <noscript> balise dans le <head>. Cela signifie que le navigateur ne traitera pas ces styles à moins que JavaScript ne soit désactivé.

Styles de mise au point et couleurs forcées

Styles de mise au point

Le thème Olivero a des styles de focus très robustes qui s’intègrent dans l’apparence du thème. Les styles de focus sont un aspect extrêmement important de l’accessibilité que nous ne voulions pas négliger.

Styles de mise au point
(Grand aperçu)

Mode couleurs forcées

Le thème Olivero et son système de navigation sont largement testés dans des couleurs forcées en utilisant le mode Windows à contraste élevé. En plus de Microsoft Edge, nous effectuons également des tests dans Chrome et Firefox. Nous l’avons également testé dans plusieurs schémas de couleurs à contraste élevé, y compris clair sur sombre, sombre sur clair et quelques schémas personnalisés que nous avons créés.

Mode couleurs forcées
(Grand aperçu)

Toutes les icônes sont soit créées à l’aide de bordures (qui deviennent apparentes lorsqu’elles sont dans des couleurs forcées), soit utilisent le forced-colors: active media query pour s’assurer qu’il est visible dans n’importe quel jeu de couleurs. De plus, nous utilisons le CanvasText couleur système pour définir la couleur d’arrière-plan de la superposition, qui fournit une limite visuelle au menu mobile.

L’accessibilité est un voyage

Pour répondre à nos exigences, nous avons largement testé Olivero sur divers appareils et technologies d’assistance. Nous avons également travaillé avec la Fédération nationale des aveugles pour effectuer des tests supplémentaires sur les lecteurs d’écran. En cours de route, nous avons appris de nombreuses leçons et techniques pour nous assurer que le système de navigation d’Olivero est utilisable par toutes les personnes utilisant n’importe quel type d’appareil.

Cela étant dit, l’accessibilité est un voyage. Il reste sans aucun doute des problèmes d’accessibilité qui apparaîtront tout au long de la durée de vie de ce thème, et nous les corrigerons lorsqu’ils se produiront. Le code est GPL open source gratuite (les exemples ci-dessus sont simplifiés), et nous espérons que vous pourrez profiter de ces leçons pour améliorer les systèmes de navigation sur le web 💙 !

Éditorial fracassant(yk, il)




Source link