Una guida per sviluppatori alle etichette ARIA che aiutano davvero
Le etichette ARIA non sono uno strato magico di accessibilità. Usate bene, rendono i controlli comprensibili. Usate con leggerezza, nascondono testo utile e creano interfacce confuse.
Indice
- Le etichette ARIA servono per i nomi, non per le scuse
- Il nome accessibile, in parole semplici
- Prima regola: preferisci HTML nativo ed etichette visibili
- Quando `aria-label` è lo strumento giusto
- Quando `aria-label` è lo strumento sbagliato
- Usa `aria-labelledby` quando il testo visibile esiste già
- Usa `aria-describedby` per il testo di aiuto, non per il nome
- I controlli ripetuti hanno bisogno di nomi univoci
- Non etichettare tutto
- Controlla il nome calcolato, non solo il codice
- Una checklist pratica di revisione
- La disciplina silenziosa di una buona ARIA
Le etichette ARIA servono per i nomi, non per le scuse
ARIA è utile, ma spesso viene usato come toppa per HTML poco chiaro. È lì che i team finiscono nei guai.
L’esempio più comune è aria-label. Sembra innocuo: aggiungi una stringa, soddisfi un linter e vai avanti. Ma un nome accessibile non è decorazione. È il nome che molte tecnologie assistive espongono agli utenti quando navigano tra pulsanti, link, campi modulo, intestazioni, landmark e controlli.
Se quel nome è vago, duplicato, obsoleto o diverso dall’etichetta visibile, l’interfaccia diventa più difficile da usare. A volte peggio: aria-label può sovrascrivere testo migliore che era già presente nel DOM.
L’obiettivo non è aggiungere più ARIA. L’obiettivo è rendere chiari il nome, il ruolo, lo stato e lo scopo di ogni elemento dell’interfaccia.
Il nome accessibile, in parole semplici
La maggior parte degli elementi interattivi ha un nome accessibile. I lettori di schermo usano quel nome per annunciare che cos’è l’elemento.
Per esempio:
<button>Save changes</button>
Un lettore di schermo può annunciare qualcosa come: “Salva modifiche, pulsante.” Il ruolo deriva dall’elemento nativo button. Il nome deriva dal testo al suo interno.
Questo è il caso ideale: testo visibile e nome accessibile coincidono.
Gli attributi di etichettatura ARIA diventano utili quando l’interfaccia visibile non fornisce un nome completo, oppure quando il nome deve provenire da un altro elemento. Gli attributi principali sono:
aria-label: fornisce una stringa direttamente sull’elemento.aria-labelledby: punta a uno o più elementi il cui testo diventa il nome.aria-describedby: punta a testo descrittivo di supporto, non al nome principale.
Questi tre attributi sono correlati, ma non intercambiabili.
Prima regola: preferisci HTML nativo ed etichette visibili
Se puoi inserire testo visibile nel controllo, fallo prima.
Questo è meglio:
<button>Delete invoice</button>
Di questo:
<button aria-label="Delete invoice">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Il secondo pattern è valido per un pulsante solo icona. Ma se il design può tollerare testo visibile, il testo visibile aiuta tutti: utenti di lettori di schermo, utenti di riconoscimento vocale, persone sotto carico cognitivo, persone che scansionano rapidamente e persone che usano strumenti di traduzione.
Questo è un tema ricorrente nel lavoro sull’accessibilità. HTML nativo e affordance visibili risolvono più problemi dei metadati nascosti. Lo stesso principio si applica più in generale alla semantica dei pulsanti; se il tuo team sta facendo audit dei controlli UI, la nostra checklist per pulsanti web accessibili è un buon complemento a questa guida.
Quando aria-label è lo strumento giusto
Usa aria-label quando un elemento ha bisogno di un nome accessibile e non esiste testo visibile adatto da referenziare.
Il caso classico è un pulsante solo icona:
<button aria-label="Search">
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
<!-- icon -->
</svg>
</button>
Questo è ragionevole. L’icona visibile suggerisce la ricerca, ma il path SVG in sé non fornisce un nome affidabile. aria-label ne fornisce uno.
Altri casi validi includono:
- Un pulsante di chiusura rappresentato solo da una “X”.
- Un landmark di navigazione che richiede un nome più specifico, come
aria-label="Product". - Un controllo ripetuto in cui il contesto visibile non fa parte del testo del pulsante.
Per esempio:
<nav aria-label="Primary">
...
</nav>
<nav aria-label="Footer">
...
</nav>
Entrambi sono landmark di navigazione, ma le loro etichette aiutano gli utenti a distinguerli quando si spostano per landmark.
Quando aria-label è lo strumento sbagliato
Non aggiungere aria-label solo perché un test dice che un elemento ha bisogno di un’etichetta. Correggi prima il markup.
Sbagliato:
<div role="button" tabindex="0" aria-label="Submit">Submit</div>
Meglio:
<button>Submit</button>
Il primo esempio crea lavoro inutile. Ora devi ricreare comportamento da tastiera, stati disabilitati, comportamento nei form e aspettative che i pulsanti nativi forniscono già.
Evita anche di usare aria-label per rinominare testo visibile in modo da cambiarne il significato.
<button aria-label="Delete invoice">Remove</button>
Sembra una cosa minore, ma può confondere gli utenti che si affidano all’input vocale. Se un pulsante visibile dice “Remove”, ma il suo nome accessibile è “Delete invoice”, un utente che prova a dire “clicca Remove” potrebbe non ottenere il risultato atteso. Il requisito WCAG “label in name” esiste proprio per questo motivo: il testo visibile dovrebbe in genere essere contenuto nel nome accessibile.
Una versione migliore:
<button aria-label="Remove invoice">Remove</button>
Spesso ancora meglio:
<button>Remove invoice</button>
Usa aria-labelledby quando il testo visibile esiste già
Se il testo dell’etichetta è già nella pagina, aria-labelledby di solito è migliore di aria-label.
Esempio:
<h2 id="billing-title">Billing address</h2>
<section aria-labelledby="billing-title">
...
</section>
Il nome accessibile della sezione ora proviene dall’intestazione visibile. Eviti di duplicare stringhe, riducendo errori di traduzione ed etichette obsolete.
Questo è particolarmente utile per i gruppi di campi modulo:
<fieldset aria-labelledby="shipping-speed-title">
<legend id="shipping-speed-title">Shipping speed</legend>
<label>
<input type="radio" name="shipping" value="standard">
Standard
</label>
<label>
<input type="radio" name="shipping" value="express">
Express
</label>
</fieldset>
In molti casi, il legend nativo è sufficiente senza ARIA. Il punto è che le etichette visibili dovrebbero guidare. ARIA dovrebbe collegare significato esistente, non crearne una seconda versione privata.
Usa aria-describedby per il testo di aiuto, non per il nome
Una descrizione non è un’etichetta.
Considera questo campo:
<label for="password">Password</label>
<input id="password" type="password" aria-describedby="password-help">
<p id="password-help">Use at least 12 characters.</p>
Il nome accessibile è “Password.” La descrizione è “Use at least 12 characters.” Un lettore di schermo può annunciare entrambi, ma hanno scopi diversi.
Non fare questo:
<input type="password" aria-label="Use at least 12 characters">
Così il campo prende il nome dall’istruzione, non dal concetto. Un utente che naviga un form vuole sapere prima che cos’è il campo, poi quali vincoli si applicano.
Questa distinzione conta anche negli stati di errore:
<label for="email">Email</label>
<input
id="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
<p id="email-error">Enter an email address in the format [email protected].</p>
L’etichetta resta stabile. Il messaggio di errore diventa contesto di supporto.
I controlli ripetuti hanno bisogno di nomi univoci
Liste e card sono i contesti in cui le etichette ARIA diventano spesso necessarie.
Sbagliato:
<button>Delete</button>
<button>Delete</button>
<button>Delete</button>
Un utente di lettore di schermo che naviga per pulsanti può sentire “Delete, pulsante” tre volte senza contesto.
Corretto:
<button aria-label="Delete report: Q4 revenue">Delete</button>
<button aria-label="Delete report: Hiring plan">Delete</button>
<button aria-label="Delete report: Vendor list">Delete</button>
Questo è un uso legittimo di aria-label: il testo visibile rimane conciso, mentre il nome accessibile include l’oggetto.
Ma usa questo pattern con attenzione. Se il nome dell’oggetto è visibile nelle vicinanze, aria-labelledby può essere più manutenibile:
<article>
<h3 id="report-q4">Q4 revenue</h3>
<button aria-labelledby="delete-q4 report-q4" id="delete-q4">Delete</button>
</article>
Il nome accessibile diventa “Delete Q4 revenue.” Questo evita di duplicare il titolo del report in un attributo.
Non etichettare tutto
Non ogni elemento ha bisogno di un’etichetta ARIA.
Di solito il testo statico non ne ha bisogno. Le icone decorative non ne hanno bisogno. I contenitori non ne hanno bisogno, a meno che non abbiano un landmark significativo o un ruolo widget. Etichettare troppo può rendere una pagina rumorosa e più difficile da navigare.
Per le immagini, usa il modello specifico delle immagini: le immagini significative hanno bisogno di un alt utile; le immagini decorative hanno bisogno di un alt="" vuoto. Non usare le etichette ARIA come sostituto di un buon testo immagine. Se il tuo team sta mescolando questi concetti, rivedi il testo alt pragmatico per le immagini e separa le alternative per le immagini dai nomi dei controlli.
Un errore comune è assegnare un aria-label a ogni SVG. Se l’SVG è dentro un pulsante e il pulsante ha già un nome, l’icona di solito dovrebbe essere nascosta alle tecnologie assistive:
<button aria-label="Open menu">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Altrimenti, l’utente potrebbe sentire annunci ridondanti o strani a seconda della combinazione di browser e tecnologia assistiva.
Controlla il nome calcolato, non solo il codice
I bug di accessibilità spesso sopravvivono alla code review perché il markup sembra plausibile.
Gli strumenti per sviluppatori dei browser moderni possono mostrare l’albero di accessibilità calcolato. In Chrome, Edge, Firefox e Safari, ispeziona l’elemento e cerca informazioni di accessibilità come ruolo, nome e descrizione. Stai controllando tre cose:
- Il ruolo è quello che ti aspetti?
- Il nome accessibile è chiaro e specifico?
- La descrizione è utile senza sostituire il nome?
Poi testa alcuni flussi con un vero lettore di schermo. Non devi diventare un esperto di tecnologie assistive a tempo pieno per cogliere le basi. Su macOS, VoiceOver è integrato. Su Windows, NVDA è molto usato e gratuito. Su mobile, testa con VoiceOver su iOS e TalkBack su Android quando pertinente.
Gli strumenti automatici sono utili, ma non possono dire in modo affidabile se “Apri”, “Leggi altro” o “Elimina” siano sufficientemente contestuali. Considera l’automazione come una rete, non come un giudice. È simile agli audit di performance: un report può indicarti aree sospette, ma devi comunque interpretarne l’impatto. Lo stesso approccio calmo che consigliamo per leggere un report Lighthouse senza andare nel panico si applica anche qui.
Una checklist pratica di revisione
Prima di pubblicare etichette ARIA, chiediti:
- Potrebbe essere HTML nativo invece?
- C’è testo visibile che dovrebbe essere usato come etichetta?
- Se esiste testo visibile, il nome accessibile lo include?
- I controlli ripetuti sono univoci quando vengono navigati fuori dal contesto visivo?
- Il testo di aiuto è collegato con
aria-describedby, non forzato nell’etichetta? - Le icone decorative sono nascoste alle tecnologie assistive?
- Qualcuno ha controllato il nome accessibile calcolato negli strumenti di sviluppo del browser?
- È stato fatto almeno un passaggio con un vero lettore di schermo per il flusso critico?
Questa checklist intercetta la maggior parte dei problemi di etichettatura prima che diventino problemi per gli utenti.
La disciplina silenziosa di una buona ARIA
Un buon lavoro con ARIA raramente è spettacolare. È soprattutto moderazione.
Usa pulsanti reali. Usa etichette reali. Mantieni allineati nomi visibili e accessibili. Aggiungi aria-label solo quando non c’è una fonte visibile migliore. Usa aria-labelledby quando la pagina contiene già il testo giusto. Usa aria-describedby per istruzioni di supporto ed errori.
La piattaforma web offre molto gratis agli sviluppatori quando la usiamo direttamente. ARIA esiste per colmare le lacune. La competenza sta nel sapere quando c’è davvero una lacuna.