Creare la navigazione principale di un sito web

Questo tutorial descrive come creare un sistema di navigazione principale accessibile in un sito web. Imparerai a conoscere l'HTML semantico, l'accessibilità e come l'utilizzo degli attributi ARIA a volte può fare più male che bene.

Manuel Matuzović
Manuel Matuzović

Esistono molti modi diversi per creare la navigazione principale di un sito web in termini di stile, funzionalità, markup e informazioni semantiche di base. Se l'implementazione è troppo minimalista, può funzionare per la maggior parte delle persone, ma l'esperienza utente (UX) potrebbe non essere eccezionale. Se è troppo ingegnerizzato, potrebbe confondere gli utenti o persino ostacolare del tutto l'accesso.

Per la maggior parte dei siti web, lo scopo è realizzare qualcosa che non sia né troppo semplice né troppo complicato.

Creazione livello per livello

In questo tutorial inizierai con una configurazione di base e aggiungerai funzionalità livello per livello fino a un punto in cui fornisci informazioni, stili e funzionalità sufficienti per soddisfare la maggior parte degli utenti. A questo scopo, occorre utilizzare il principio del miglioramento progressivo, in base al quale si inizia dalla soluzione più fondamentale e robusta e si aggiungono progressivamente livelli di funzionalità. Se per qualche motivo un livello non funziona, la navigazione continuerà a funzionare perché ritorna correttamente al livello sottostante.

Struttura di base

Per una navigazione di base sono necessari due elementi: elementi <a> e alcune righe di CSS per migliorare lo stile e il layout predefiniti dei link.

<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);
}
Visualizza il Passaggio 1. HTML e CSS di base" su CodePen.

Questo approccio funziona bene per la maggior parte degli utenti, indipendentemente dalla modalità di accesso al sito. La navigazione è accessibile con un mouse, una tastiera, un dispositivo touch o uno screen reader, ma c'è margine di miglioramento. Puoi migliorare l'esperienza estendendo questo pattern di base con funzionalità e informazioni aggiuntive.

Ecco quello che puoi fare:

  • Evidenzia la pagina attiva.
  • Annuncia il numero di elementi agli utenti di screen reader.
  • Aggiungi un punto di riferimento e consenti agli utenti di screen reader di accedere direttamente alla navigazione utilizzando una scorciatoia.
  • Nascondi la navigazione nelle aree visibili strette.
  • Migliora lo stile della messa a fuoco.
di Gemini Advanced.

Evidenzia la pagina attiva

Per evidenziare la pagina attiva, puoi aggiungere un corso al link corrispondente.

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

Il problema di questo approccio è che trasmette le informazioni quali link sono attivi puramente visivamente. Un utente cieco di screen reader non è riuscito a distinguere la pagina attiva dalle altre pagine. Fortunatamente, lo standard ARIA (Accessible Rich Internet Applications) offre un modo per comunicare queste informazioni anche semanticamente. Utilizza l'attributo e il valore aria-current=&quot;page&quot; anziché una classe.

aria-current (stato) indica l'elemento che rappresenta l'elemento corrente all'interno di un contenitore o di un insieme di elementi correlati. Token di pagina utilizzato per indicare un link all'interno di un insieme di link di impaginazione, in cui lo stile del link rappresenta la pagina attualmente visualizzata. [Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)
di Gemini Advanced.

Con l'attributo aggiuntivo, uno screen reader ora annuncia qualcosa come "pagina corrente, link, Chi siamo". anziché semplicemente "link, Chi siamo".

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

Un effetto collaterale pratico consiste nell'utilizzare l'attributo per selezionare il link attivo in CSS, rendendo obsoleta la classe active-page.

<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);
}
Visualizza il Passaggio 2: evidenzia la pagina attiva su CodePen.

Annuncia il numero di elementi

Osservando il navigatore, gli utenti vedenti possono capire che contiene solo quattro link. Un utente cieco di screen reader non può ottenere queste informazioni così rapidamente. Potrebbero dover esaminare l'intero elenco di link. Questo potrebbe non essere un problema se l'elenco è breve come in questo esempio, ma se contiene 40 link questa attività può essere complicata. Se un utente di screen reader sa in anticipo che la navigazione contiene molti link, potrebbe decidere di utilizzare un metodo di navigazione diverso e più efficiente, come la ricerca sul sito.
Un modo efficace per comunicare in anticipo il numero di elementi consiste nell'aggregare ogni link in un elemento dell'elenco (<li>), nidificato in un elenco non ordinato (<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>

Quando un utente di screen reader trova l'elenco, il software annuncerà, ad esempio, "elenco, 4 elementi".

Ecco una demo della navigazione utilizzata con lo screen reader NVDA su Windows.

Ora devi adattare lo stile per renderlo simile a prima.

/* 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'utilizzo degli elenchi può offrire molti vantaggi agli utenti di screen reader:

  • Può ottenere il numero totale di elementi prima di interagire con essi.
  • Possono utilizzare scorciatoie per passare da un elemento all'altro.
  • Possono utilizzare scorciatoie per passare da un elenco all'altro.
  • Lo screen reader potrebbe annunciare l'indice dell'elemento corrente (ad esempio "elemento dell'elenco, due di quattro").

Inoltre, se la pagina viene presentata senza CSS, l'elenco mostra i link come un gruppo coerente di elementi anziché solo come una pila di link.

Una caratteristica degna di nota di VoiceOver in Safari è che tutti questi vantaggi si perdono se imposti list-style: none. Questo è dovuto alla progettazione. Il team di WebKit ha deciso di rimuovere la semantica di un elenco, quando un elenco non ha l'aspetto di un elenco. A seconda della complessità della navigazione, questo potrebbe non essere un problema. Da un lato, la navigazione è ancora utilizzabile e influisce solo su VoiceOver in Safari. VoiceOver con Chrome o Firefox continua a annunciare il numero di elementi, così come altri screen reader come NVDA. D'altra parte, le informazioni semantiche potrebbero essere molto utili in alcune situazioni. Per prendere questa decisione, devi testare la navigazione con utenti effettivi di screen reader e ricevere il loro feedback. Se decidi che è necessario che VoiceOver in Safari si comporti come tutti gli altri screen reader, puoi aggirare il problema impostando in modo esplicito il ruolo dell'elenco ARIA su <ul>. Questa operazione ripristina il comportamento allo stato precedente alla rimozione dello stile dell'elenco. Visivamente, l'elenco appare sempre lo stesso.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Visualizza il Passaggio 3: comunicazione del numero di elementi su CodePen.

Aggiungi un punto di riferimento

Con il minimo sforzo, hai apportato ottimi miglioramenti per gli utenti di screen reader, ma c'è un'altra cosa che puoi fare. semanticamente, la navigazione è solo un elenco di link ed è difficile dire che questo elenco specifico è la navigazione principale del tuo sito web. Puoi trasformare questo elenco ordinario in un elenco di navigazione aggregando <ul> in un elemento <nav>.

L'utilizzo dell'elemento <nav> offre diversi vantaggi. In particolare, uno screen reader annuncia un'azione simile alla "navigazione" quando l'utente interagisce con l'app e aggiunge un punto di riferimento alla pagina. I punti di riferimento sono aree speciali nella pagina, come <header>, <footer> o <main>, a cui può passare uno screen reader. Avere dei punti di riferimento in una pagina può essere utile, perché consente agli utenti di screen reader di accedere direttamente alle aree importanti della pagina senza dover interagire con il resto della pagina. Ad esempio, puoi passare da un punto di riferimento all'altro premendo il tasto D di NVDA. In Voice Over puoi utilizzare il rotore per elencare tutti i punti di riferimento della pagina premendo VO + U.

Un elenco di quattro punti di riferimento: banner, navigazione, principale, informazioni sui contenuti.
Rotore in VoiceOver che elenca tutti i punti di riferimento su una pagina.

In questo elenco sono presenti quattro punti di riferimento: banner, che è l'elemento <header>, navigazione è l'elemento <nav>, principale l'elemento <main> e le informazioni sui contenuti sono l'elemento <footer>. Questo elenco non deve essere troppo lungo, devi solo contrassegnare come punti di riferimento le parti fondamentali dell'interfaccia utente, ad esempio la ricerca sul sito, una navigazione locale o un'impaginazione.

Se su una singola pagina sono presenti una navigazione in tutto il sito, una navigazione locale per la pagina e un'impaginazione, potresti avere anche tre elementi <nav>. Non c'è problema, ma ora ci sono tre punti di riferimento per la navigazione e semanticamente sono tutti uguali. È difficile distinguerli, a meno che tu non conosca molto bene la struttura della pagina.

Immagine che mostra tre punti di riferimento con la dicitura &quot;navigazione&quot;.
Il rotore di VoiceOver che elenca tre punti di riferimento di navigazione senza etichetta.

Per distinguerli, etichettali utilizzando aria-labelledby o 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>

Se l'etichetta che hai scelto esiste già da qualche parte nella pagina, puoi usare aria-labelledby e fare riferimento all'etichetta esistente usando l'attributo 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>

È sufficiente un'etichetta concisa, non essere troppo prolissi. Ometti espressioni come "navigazione" o "menu" perché lo screen reader fornisce già queste informazioni agli utenti.

Punti di riferimento
VoiceOver con elenco dei punti di riferimento "banner", "navigazione principale", "principale", "navigazione nelle pagine", "seleziona navigazione nelle pagine" e "informazioni sui contenuti".
Vedi il Passaggio 4: aggiungi un punto di riferimento sulla CodePen.

Nascondi la navigazione nelle aree visibili strette

Personalmente, non mi piace nascondere la navigazione principale nelle aree visibili strette, ma se l'elenco dei link diventa troppo lungo, non c'è modo di evitarlo. In questo caso, al posto dell'elenco, gli utenti vedranno un pulsante con l'etichetta "Menu" o l'icona di un hamburger o una loro combinazione. Se fai clic sul pulsante, l'elenco viene visualizzato e nascosto. Se conosci JavaScript e CSS di base, è un'attività fattibile, ma ci sono diversi aspetti in termini di UX e accessibilità.

  • Devi nascondere l'elenco in modo accessibile.
  • La navigazione deve essere accessibile dalla tastiera.
  • La navigazione deve comunicare se è visibile o meno.

Aggiunta del pulsante di un hamburger

Poiché segui il principio del miglioramento progressivo, vuoi assicurarti che la navigazione continui a funzionare e abbia senso anche con JavaScript disattivato.
La prima cosa di cui ha bisogno la navigazione è un pulsante a forma di hamburger. Puoi crearlo in HTML in un elemento di modello, clonarlo in JavaScript e aggiungerlo alla navigazione.

Pagina che mostra il pulsante di un hamburger.
Risultato: anziché i link, la navigazione mostra un pulsante a forma di hamburger in aree visibili strette.
<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'attributo aria-expanded indica al software dello screen reader se l'elemento controllato dal pulsante è espanso o meno.
  2. aria-label assegna al pulsante il cosiddetto nome accessibile, un'alternativa di testo all'icona dell'hamburger.
  3. Puoi nascondere <svg> dalle tecnologie per la disabilità utilizzando aria-hidden perché presenta già un'etichetta di testo fornita da aria-label.
  4. aria-controls indica alle tecnologie per la disabilità, che supporta l'attributo (ad esempio JAWS), quale elemento controlla il pulsante.
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. Gli utenti possono chiudere la navigazione in qualsiasi momento, ad esempio premendo il tasto Esc.
  2. È importante utilizzare insertBefore anziché appendChild perché il pulsante deve essere il primo elemento della navigazione. Se l'utente di una tastiera o di uno screen reader preme Tab dopo aver fatto clic sul pulsante, si aspetta di impostare lo stato attivo sul primo elemento dell'elenco. Se il pulsante viene dopo l'elenco, ciò non avviene.

A questo punto, reimposti lo stile predefinito del pulsante e assicurati che sia visibile solo in aree visibili strette.

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

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
Vedi il Passaggio 5: aggiungi un pulsante hamburger sulla CodePen.

La lista sta per essere nascosta

Prima di nascondere l'elenco, posiziona e personalizza la navigazione e l'elenco in modo che il layout sia ottimizzato per aree visibili ristrette, ma venga comunque visualizzato correttamente su schermi più grandi.
Innanzitutto, rimuovi <nav> dal flusso naturale della pagina e posizionalo nell'angolo superiore dell'area visibile.

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

Poi modifica il layout nelle aree visibili strette aggiungendo una nuova proprietà personalizzata (—-nav-list-layout). Per impostazione predefinita, il layout è a colonne e passa alla riga su schermi più grandi.

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

La navigazione dovrebbe avere un aspetto simile a questo nelle aree visibili strette.

Pagina che mostra l&#39;elenco di navigazione e il pulsante hamburger.
Il pulsante a forma di hamburger e l'elenco si trovano nell'angolo superiore dell'area visibile.

Ovviamente l'elenco necessita di un po' di CSS. Lo sposteremo verso l'alto nell'angolo più in alto, lo riempiamo in verticale, applichiamo background-color e 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;
}

L'elenco dovrebbe avere un aspetto simile a questo nelle aree visibili strette, più simile a una barra laterale che a un semplice elenco.

L&#39;elenco di navigazione si apre.

Infine, nascondi l'elenco, mostralo solo quando l'utente fa clic sul pulsante una volta e nascondilo quando fa nuovamente clic. È importante nascondere solo l'elenco e non l'intera navigazione perché nasconderla significa anche nascondere un punto di riferimento importante.

In precedenza hai aggiunto un evento di clic al pulsante per attivare/disattivare il valore dell'attributo aria-expanded. Puoi utilizzare queste informazioni come condizione per mostrare e nascondere l'elenco in 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);
}

Per nascondere l'elenco, è importante utilizzare una dichiarazione della proprietà come visibility: hidden o display: none anziché opacity: 0 o translateX(100%). Queste proprietà assicurano che non sia possibile attivare i link quando la navigazione è nascosta. L'utilizzo di opacity o translate comporterà la rimozione dei contenuti visivamente in modo che i link siano invisibili, ma siano comunque accessibili utilizzando la tastiera, il che risulterebbe fuorviante e frustrante. L'utilizzo di visibility o display lo nasconde visivamente e lo rende inaccessibile, nascondendolo per tutti gli utenti.

Visualizza il Passaggio 6: nascondi l'elenco.

Animazione dell'elenco

Se ti stai chiedendo perché usare visibility: hidden; su display: none;, è perché puoi animare la visibilità. Ha solo due stati, hidden e visible, ma puoi combinarlo con un'altra proprietà come transform o opacity per creare un effetto slide-in o di dissolvenza. Questa operazione non funzionerebbe con display: nessuna perché la proprietà display non è animabile.

Le seguenti transizioni CSS opacity per creare un effetto di dissolvenza in entrata e in uscita.

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

Se invece vuoi animare il movimento, ti consigliamo di inserire la proprietà transition in una query multimediale prefers-reduced-motion, perché le animazioni possono provocare nausea, vertigini e mal di testa in alcuni utenti.

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

In questo modo puoi fare in modo che solo le persone che non hanno preferenze per il movimento ridotto vedano l'animazione.

Visualizza il Passaggio 7: Animazione dell'elenco su CodePen.

Migliora lo stile della messa a fuoco

Gli utenti con la tastiera fanno affidamento sugli stili di messa a fuoco degli elementi per l'orientamento e la navigazione su una pagina. Gli stili di impostazione dello stato attivo predefiniti sono meglio che nessun tipo di messa a fuoco (che si verifica se imposti outline: none), ma avere stili di messa a fuoco personalizzati più chiaramente visibili migliora l'esperienza utente.

Ecco l'aspetto degli stili predefiniti per lo stato attivo del link in Chrome 103.

Un contorno blu di 2 px attorno a un link attivo in Chrome 103.

Puoi migliorarlo fornendo stili personalizzati nei tuoi colori. Se utilizzi :focus-visible anziché :focus, consenti al browser di decidere quando è opportuno mostrare gli stili di impostazione dello stato attivo. Gli stili di :focus saranno visibili a tutti gli utenti, con mouse, tastiera e tocco, indipendentemente dal fatto che ne abbiano bisogno o meno. Con :focus-visible, il browser utilizza un'euristica interna per decidere se mostrarle solo agli utenti della tastiera o a tutti.

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

Supporto dei browser per :focus-visible

Supporto dei browser

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

Origine

Contorno di 2 px scuro ben visibile con spaziatura interna.

Esistono diversi modi per evidenziare gli elementi quando vengono selezionati. Ti consigliamo di utilizzare la proprietà outline perché non interrompe il layout, cosa che potrebbe verificarsi con border, e funziona bene con la modalità ad alto contrasto su Windows. Le proprietà che non funzionano correttamente sono background-color o box-shadow, perché potrebbero non essere visualizzate affatto con impostazioni di contrasto personalizzate.

Un sito con uno sfondo scuro con messa a fuoco evidenziata in viola.
Visualizza il Passaggio 8: migliora gli stili dello stato attivo su CodePen.

Complimenti! Hai creato una navigazione principale progressiva, semanticamente ricca, accessibile e ottimizzata per il mobile.

C'è sempre qualcosa che può essere migliorato, ad esempio:

  • Puoi prendere in considerazione l'idea di mettere lo stato attivo all'interno della navigazione o di rendere il resto della pagina inerte in aree visibili strette.
  • Puoi aggiungere un link Ignora nella parte superiore della pagina per consentire agli utenti con tastiera di saltare la navigazione.

Se ricordi com'è iniziato questo articolo, con l'obiettivo di far sì che la soluzione "non sia né troppo semplice né troppo complicata", ecco a che punto siamo ora. Tuttavia, è possibile ottimizzare una navigazione.

Esiste una chiara differenza tra navigazioni e menu. Le navigazioni sono raccolte di link per esplorare i documenti correlati. I menu sono raccolte di azioni da eseguire in un documento. A volte queste attività si sovrappongono. Potresti avere una navigazione che include anche un pulsante che esegue un'azione, come l'apertura di una finestra modale, oppure un menu in cui un'azione consente di passare a un'altra pagina, ad esempio una pagina della guida. In questo caso, è importante non combinare i ruoli ARIA, ma identificare lo scopo principale del componente e scegliere il markup e i ruoli di conseguenza.

L'elemento <nav> ha un ruolo di navigazione ARIA implicito che è sufficiente a comunicare che l'elemento è una navigazione, ma spesso i siti utilizzano anche menu, barra dei menu ed voce di menu. Dal momento che a volte usiamo questi termini in modo intercambiabile, pensare che la loro combinazione per migliorare l'esperienza degli utenti di screen reader potrebbe avere senso. Prima di capire perché generalmente non è così, diamo un'occhiata alla definizione ufficiale di questi ruoli.

Ruolo relativo alla navigazione

Una raccolta di elementi di navigazione (di solito link) per la navigazione nel documento o nei documenti correlati.

navigazione (ruolo) WAI-ARIA 1.1

Il ruolo del menu

Un menu è spesso un elenco di azioni o funzioni comuni che l'utente può richiamare. Il ruolo del menu è appropriato quando un elenco di voci di menu viene presentato in modo simile a un menu in un'applicazione desktop.

menu (ruolo) WAI-ARIA 1.1

Ruolo nella barra dei menu

Presentazione di un menu che solitamente rimane visibile e solitamente viene presentato in orizzontale. Il ruolo nella barra dei menu consente di creare una barra dei menu simile a quella delle applicazioni desktop Windows, Mac e Gnome. Una barra dei menu consente di creare un insieme coerente di comandi utilizzati di frequente. Gli autori devono assicurarsi che l'interazione con la barra dei menu sia simile alla tipica interazione con la barra dei menu in una Graphic User Interface per computer.

barra dei menu (ruolo) WAI-ARIA 1.1

Il ruolo Voce di menu

Un'opzione in una serie di opzioni contenute in un menu o in una barra dei menu.

menuitem (role) WAI-ARIA 1.1

Le specifiche qui sono molto chiare: usa la navigazione per navigare nel documento o tra i documenti correlati e usa i menu solo per un elenco di azioni o funzioni simili ai menu delle applicazioni desktop. Se non stai creando il prossimo documento Google, probabilmente non hai bisogno dei ruoli di menu per la navigazione principale.

Quando è appropriato un menu?

L'utilizzo principale delle voci di menu non è la navigazione, ma per eseguire azioni. Supponiamo che tu abbia un elenco o una tabella di dati e che gli utenti possano eseguire determinate azioni su ogni elemento dell'elenco. Puoi aggiungere un pulsante a ogni riga e mostrare le azioni quando gli utenti fanno clic su di esso.

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

Implicazioni dell'utilizzo dei ruoli nei menu

È molto importante utilizzare questi ruoli del menu in modo saggio perché possono andare storti.

I menu prevedono una determinata struttura DOM. menuitem deve essere un elemento secondario diretto di menu. Il seguente codice potrebbe interrompere il comportamento semantico:

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

Gli utenti esperti si aspettano che determinate scorciatoie da tastiera funzionino con i menu e le barre dei menu. In base alla Guida alle pratiche di creazione di ARA (APG), ciò include:

  • Invio e la barra spaziatrice per selezionare le voci del menu.
  • I tasti freccia in tutte le direzioni per spostarti tra gli elementi.
  • I tasti Home e Fine per spostare lo stato attivo rispettivamente sul primo o sull'ultimo elemento.
  • A-z per spostare lo stato attivo sulla voce di menu successiva con un'etichetta che inizia con il carattere digitato.
  • Esc per chiudere il menu.

Se uno screen reader rileva un menu, il software potrebbe cambiare automaticamente la modalità di navigazione, consentendo l'utilizzo delle scorciatoie menzionate in precedenza. Gli utenti di screen reader inesperti potrebbero non riuscire a utilizzare il menu perché non conoscono queste scorciatoie o non sanno come utilizzarle.

Lo stesso vale per gli utenti con tastiera che potrebbero aspettarsi di utilizzare Maiusc e Maiusc + Tab.

Sono molti gli aspetti da considerare per la creazione di menu e barre dei menu, ma è importante capire se è consigliabile utilizzarli prima di iniziare. Quando crei un tipico sito web, l'elemento nav con un elenco e i link è tutto quello di cui hai bisogno. Sono incluse anche le applicazioni a pagina singola (APS) o le app web. Lo stack sottostante non è importante. A meno che tu non stia creando un'applicazione molto simile a un'applicazione desktop, evita i ruoli nei menu.

Risorse aggiuntive

Immagine hero di Mick Haupt