Questo tutorial descrive come creare una navigazione principale accessibile di 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.
Esistono molti modi diversi per creare il menu di navigazione principale di un sito web, in termini di stile, funzionalità e informazioni semantiche e di markup sottostanti. Se l'implementazione è troppo minimalista, funziona per la maggior parte degli utenti, ma l'esperienza utente (UX) potrebbe non essere ottimale. Se è troppo complessa, potrebbe confondere gli utenti o addirittura impedire loro di accedervi.
Per la maggior parte dei siti web, è preferibile creare qualcosa che non sia né troppo semplice né troppo complicato.
Costruzione strato dopo strato
In questo tutorial inizi con una configurazione di base e aggiungi funzionalità livello per livello fino a un punto in cui fornisci informazioni, stili e funzionalità sufficienti per soddisfare la maggior parte degli utenti. Per farlo, utilizzi il principio di miglioramento progressivo, che prevede di iniziare con la soluzione più fondamentale e solida e di aggiungere progressivamente livelli di funzionalità. Se per qualche motivo un livello non funziona, la navigazione continuerà a funzionare perché tornerà 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);
}
Questo metodo funziona bene per la maggior parte degli utenti, indipendentemente dal modo in cui accedono al sito. La navigazione è accessibile con un mouse, una tastiera, un dispositivo touch o uno screen reader, ma c'è spazio per miglioramenti. Puoi migliorare l'esperienza estendendo questo modello 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.
- Nascondere la navigazione nelle visualizzazioni con viewport ristrette.
- Migliora lo stile della messa a fuoco.
Evidenzia la pagina attiva
Per evidenziare la pagina attiva, puoi aggiungere una classe 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 Accessible Rich Internet Applications (ARIA) offre un modo per comunicare queste informazioni anche in modo semantico. Utilizza l'attributo e il valore aria-current="page" 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)
Con l'attributo aggiuntivo, uno screen reader ora annuncia qualcosa di simile a "pagina corrente, link, Chi siamo" anziché solo "link, Chi siamo".
<a href="/about-us" aria-current="page" class="active-page">About us</a>
Un pratico effetto collaterale è che puoi 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);
}
Annuncia il numero di articoli
Osservando il menu di navigazione, gli utenti vedenti possono capire che contiene solo quattro link. Un utente cieco che utilizza uno 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 modo di navigazione diverso ed più efficiente, come la ricerca sul sito.
Un modo pratico per comunicare in anticipo il numero di elementi è racchiudere 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 uno screen reader trova l'elenco, il software annuncia qualcosa di simile a "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ò avere molti vantaggi per gli utenti di screen reader:
- Possono ottenere il numero totale di articoli prima di interagire con gli articoli.
- Potrebbero utilizzare scorciatoie per passare da un elemento all'altro dell'elenco.
- Potrebbero 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 è presentata senza CSS, l'elenco mostra i link come un gruppo coerente di elementi anziché come una serie di link.
Un dettaglio importante di VoiceOver in Safari è che perdi tutti questi vantaggi quando imposti list-style: none
. Si tratta del comportamento previsto. Il team di WebKit ha deciso di rimuovere la semantica dell'elenco quando un elenco non ha l'aspetto di un elenco. A seconda della complessità della navigazione, questo potrebbe o meno essere un problema. Da un lato, la navigazione è ancora utilizzabile e riguarda solo VoiceOver in Safari. VoiceOver con Chrome o Firefox continua ad 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>
. In questo modo, il comportamento torna allo stato precedente alla rimozione dello stile dell'elenco. Visivamente, l'elenco non cambia.
<ul role="list">
<li>
<a href="/home">Home</a>
</li>
...
</ul>
Aggiungere un punto di riferimento
Con poco sforzo, hai apportato grandi miglioramenti per gli utenti di screen reader, ma c'è ancora un'altra cosa che puoi fare. Dal punto di vista semantico, la navigazione è ancora solo un elenco di link ed è difficile capire che questo elenco specifico è la navigazione principale del tuo sito web. Puoi trasformare questo elenco normale in un elenco di navigazione inserendo <ul>
in un elemento <nav>
.
L'utilizzo dell'elemento <nav>
offre diversi vantaggi. In particolare, uno screen reader annuncia qualcosa come "navigazione" quando l'utente interagisce con esso 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. La presenza di punti di riferimento in una pagina può essere utile perché consente agli utenti di screen reader di accedere direttamente alle regioni 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 in NVDA. In Voice Over puoi utilizzare il rotore per elencare tutti i punti di riferimento della pagina premendo VO + U.
In questo elenco sono presenti quattro elementi di riferimento: banner, che è l'elemento <header>
, navigazione, che è l'elemento <nav>
, principale, che è l'elemento <main>
e informazioni sui contenuti, che è 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 hai una navigazione a livello di sito, una navigazione locale per la pagina e una paginazione in una singola pagina, potresti anche avere tre elementi <nav>
. Va bene, ma ora ci sono tre punti di riferimento di navigazione e semanticamente sono tutti uguali. È difficile distinguerli, a meno che tu non conosca molto bene la struttura della pagina.
Per distinguerli, devi etichettarli 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 utilizzare aria-labelledby
e fare riferimento all'etichetta esistente utilizzando 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.
Nascondere la navigazione nelle visualizzazioni della pagina strette
Personalmente, non amo molto nascondere la navigazione principale in viewport stretti, ma se l'elenco dei link diventa troppo lungo, non c'è modo di evitarlo. In questo caso, anziché l'elenco, gli utenti vedranno un pulsante con l'etichetta "Menu" o un'icona a forma di menu o una combinazione. Se fai clic sul pulsante, l'elenco viene visualizzato e nascosto. Se conosci JavaScript e CSS di base, è un'attività fattibile, ma devi occuparti di diversi aspetti in termini di UX e accessibilità.
- Devi nascondere l'elenco in modo accessibile.
- La navigazione deve essere accessibile tramite tastiera.
- Il sistema di navigazione deve indicare 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. Devi crearlo in HTML in un elemento del modello, clonarlo in JavaScript e aggiungerlo alla navigazione.
<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>
- L'attributo
aria-expanded
indica al software dello screen reader se l'elemento controllato dal pulsante è espanso o meno. aria-label
assegna al pulsante il cosiddetto nome accessibile, un'alternativa di testo all'icona dell'hamburger.- Nascondi
<svg>
alle tecnologie per la disabilità utilizzandoaria-hidden
perché ha già un'etichetta di testo fornita daaria-label
. aria-controls
indica alla tecnologia 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);
- È comodo per gli utenti avere la possibilità di chiudere la navigazione in qualsiasi momento, ad esempio premendo il tasto Esc.
- È importante utilizzare
insertBefore
anzichéappendChild
perché il pulsante deve essere il primo elemento della navigazione. Se un utente con tastiera o screen reader preme Tab dopo aver fatto clic sul pulsante, si aspetta che venga visualizzato il primo elemento dell'elenco. Se il pulsante si trova dopo l'elenco, non è così.
Poi, reimposta lo stile predefinito del pulsante e assicurati che sia visibile solo in visualizzazioni della pagina strette.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
}
}
/* Reset button styling */
button {
all: unset;
display: var(--nav-button-display, flex);
}
Nascondere l'elenco
Prima di nascondere l'elenco, posiziona e personalizza la navigazione e l'elenco in modo che il layout sia ottimizzato per le visualizzazioni della pagina strette, ma sia comunque piacevole da vedere su schermi più grandi.
Innanzitutto, rimuovi il <nav>
dal flusso naturale della pagina e posizionalo nell'angolo in alto 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)
. Il layout è a colonne per impostazione predefinita e passa a righe 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.
L'elenco ovviamente richiede 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 questo aspetto nelle visualizzazioni della pagina strette, più simile a una barra laterale che a un semplice elenco.
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é nascondere la navigazione significherebbe 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 di proprietà come visibility: hidden
o display: none
anziché opacity: 0
o translateX(100%)
. Queste proprietà assicurano che i link non siano attivabili 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. Se utilizzi visibility
o display
, il campo viene nascosto visivamente e reso inaccessibile, quindi non sarà visibile a nessuno.
Animazione dell'elenco
Se ti stai chiedendo perché utilizzare visibility: hidden;
anziché 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 dissolvenza. Questo non funzionerebbe con display: none 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 racchiudere la proprietà transition
in una query sui media prefers-reduced-motion perché le animazioni possono scatenare 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, l'animazione verrà visualizzata solo dalle persone che non hanno una preferenza per le animazioni ridotte.
Migliora lo stile della messa a fuoco
Gli utenti che utilizzano la tastiera si basano sugli stili di attivazione degli elementi per l'orientamento e la navigazione in 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.
Puoi migliorare la situazione fornendo i tuoi stili nei tuoi colori. Se utilizzi :focus-visible
anziché :focus
, lasci che sia il browser a decidere quando è opportuno mostrare gli stili di messa a fuoco. Gli stili :focus
saranno visibili a tutti, a prescindere dal fatto che gli utenti utilizzino mouse, tastiera o tocco. 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
Esistono diversi modi per evidenziare gli elementi quando vengono selezionati. L'utilizzo della proprietà outline
è consigliato perché non interrompe il layout, cosa che potrebbe accadere con border
, e funziona bene con la modalità ad alto contrasto su Windows. Le proprietà che non funzionano bene sono background-color
o box-shadow
, perché potrebbero non essere visualizzate con le impostazioni di contrasto personalizzate.
Complimenti! Hai creato una navigazione principale migliorata progressivamente, semanticamente ricca, accessibile e ottimizzata per il mobile.
C'è sempre qualcosa che può essere migliorato, ad esempio:
- Puoi prendere in considerazione l'idea di tenere 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 progettare una navigazione eccessiva.
Navigazioni e menu
Esiste una chiara differenza tra navigazioni e menu. Le navigazioni sono raccolte di link per la navigazione nei documenti correlati. I menu sono raccolte di azioni da eseguire in un documento. A volte queste attività si sovrappongono. Potresti avere un menu di navigazione che include anche un pulsante che esegue un'azione, ad esempio l'apertura di una finestra modale, oppure un menu in cui un'azione ti reindirizza a un'altra pagina, ad esempio una pagina di assistenza. In questi casi, è importante non combinare i ruoli ARIA, ma identificare lo scopo principale del componente e scegliere di conseguenza il markup e i ruoli.
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 scoprire perché in genere non è così, diamo un'occhiata alla definizione ufficiale di questi ruoli.
Il ruolo di navigazione
Una raccolta di elementi di navigazione (in genere link) per spostarsi nel documento o nei documenti correlati.
navigation (role) 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 menu è appropriato quando un elenco di voci di menu viene presentato in modo simile a un menu in un'applicazione desktop.
menu (role) WAI-ARIA 1.1
Il ruolo della barra dei menu
Una presentazione del menu che in genere rimane visibile e viene solitamente presentata in orizzontale. Il ruolo menubar viene utilizzato per creare una barra dei menu simile a quelle presenti nelle applicazioni desktop Windows, Mac e Gnome. Una barra dei menu viene utilizzata per creare un insieme coerente di comandi di uso 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.
menubar (role) WAI-ARIA 1.1
Ruolo Voce di menu
Un'opzione in un insieme di scelte 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 la prossima versione di Documenti Google, probabilmente non hai bisogno di nessuno dei ruoli del menu per la navigazione principale.
Quando è opportuno utilizzare un menu?
L'uso principale delle voci di menu non è la navigazione, ma l'esecuzione di 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 sul pulsante.
<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 con saggezza, perché possono verificarsi molti errori.
I menu richiedono 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 authoring ARIA (APG), sono inclusi:
- Invio e Barra spaziatrice per selezionare le voci del menu.
- 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 sopra menzionate. 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.
Quando crei menu e barre dei menu, devi prendere in considerazione molti fattori, a partire dall'opportunità di utilizzarli. 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 qualcosa di molto simile a un'applicazione desktop, evita i ruoli di menu.
Risorse aggiuntive
- Fixing Lists di Scott O'Hara.
- Non utilizzare i ruoli dei menu ARIA per la navigazione sui siti di Adrian Roselli.
- Menu e pulsanti di menu di Heydon Pickering.
- Menu WAI-ARIA e perché dovresti gestirli con molta cura di Marco Zehe.
- Nascondere i contenuti in modo responsabile di Kitty Giraudel.
- :focus-visible Is Here di Matthias Ott.
Immagine hero di Mick Haupt