Principi di Accessibilità per sviluppo tecnologie Web

Principi di Accessibilità per sviluppo tecnologie Web

L'accessibilità web per utenti non vedenti o ipovedenti si basa su un insieme di tecniche standardizzate che permettono alle tecnologie assistive, come gli screen reader, di interpretare correttamente un'interfaccia digitale.
A differenza di un utente vedente, chi usa uno screen reader non percepisce il layout visivo: naviga il DOM in modo lineare, ascolta gli annunci vocali generati dagli attributi semantici degli elementi e interagisce esclusivamente tramite tastiera.
Senza questi metadati, componenti apparentemente funzionali diventano completamente invisibili o inutilizzabili.

Conoscere quindi principi come questi è fondamentale per qualsiasi team di sviluppo, perché i problemi di accessibilità non emergono da scelte sbagliate evidenti, ma da omissioni difficili da individuare senza una prospettiva specifica: un <div> cliccabile che funziona perfettamente con il mouse può essere totalmente irraggiungibile da tastiera; una modale visivamente ben costruita può non annunciarsi mai a uno screen reader; un campo di ricerca senza label diventa un elemento anonimo non appena il placeholder scompare durante la digitazione.
Applicare questi pattern in modo sistematico sin dalle prime fasi di sviluppo è molto più efficiente che correggere i problemi a posteriori.
Vediamoli più nel dettaglio.

1. Dichiarazione della lingua (attributo lang)

L'attributo <html lang="it"> comunica agli screen reader in quale lingua è scritto il contenuto, in modo che la sintesi vocale utilizzi le regole di pronuncia e i fonemi corretti.


2. Calcolo del nome accessibile (aria-label, aria-labelledby, <label>)

Ogni elemento interattivo e ogni campo di un modulo deve avere un nome programmatico leggibile dalle tecnologie assistive.
Senza di esso, lo screen reader annuncia solo il tipo dell'elemento (es. "pulsante") senza alcun contesto.
Utilizzato ad esempio su: campi di ricerca, pulsanti indietro, immagine mappa, valutazione a stelle, textarea note.

Esempio di uso di aria-label su un bottone con la traduzione (funzione t di i18n).

3. Pattern ARIA Dialog (role="dialog", aria-modal="true", aria-labelledby)

Le finestre modali devono essere marcate come dialog affinché lo screen reader comprenda che l'utente è entrato in un contesto separato.
aria-modal="true" impedisce al lettore di navigare il contenuto dietro l'overlay.
aria-labelledby collega il titolo annunciato del dialog al suo heading visibile.

Esempio di uso di role="dialog" e aria-labelledby. Il valore fa riferimento agli id degli elementi testuali che descrivono il dialog.

4. Gestione del focus


Quando una modale si apre, il focus deve essere spostato programmaticamente al suo interno (tabindex="-1" + .focus()).
Quando si chiude, il focus deve tornare all'elemento che l'ha attivata.
Senza questo, un utente non vedente potrebbe non accorgersi che la modale è apparsa e continuare a interagire con il contenuto in background.

Esempio di uso della funzione .focus() verso dialogPanel.

5. Navigabilità da tastiera (tabindex="0", @keydown.enter, @keydown.space)


Qualsiasi elemento cliccabile visivamente che non sia un <button> o un <a> nativo deve ricevere tabindex="0" per essere raggiungibile tramite Tab, e deve rispondere ai tasti Invio e Spazio.


6. Assegnazione di ruoli semantici (role="button", role="radio", role="radiogroup", role="heading")


Gli elementi <div> e <span> non hanno semantica implicita. Assegnare un ruolo ARIA esplicito comunica lo scopo dell'elemento agli screen reader:

- un <div> con role="button" viene annunciato come pulsante;
- un contenitore di valutazione a stelle con role="radiogroup" segnala un gruppo a scelta singola;
- i titoli di sezione con role="heading" appaiono nella lista di navigazione per titoli dello screen reader.

Esempio di uso dell'attributo role="dialog".

7. Regioni ARIA live (aria-live, role="status", role="alert")


I cambiamenti dinamici del contenuto (risultati di ricerca che appaiono, stati di caricamento che si risolvono, errori) sono invisibili agli screen reader a meno che non siano racchiusi in una live region.
aria-live="polite" mette in coda un annuncio dopo il parlato corrente; aria-live="assertive" / role="alert" interrompe immediatamente per messaggi urgenti.
Utilizzato per i risultati della ricerca, gli overlay di caricamento e gli errori API.

Esempio di aria-live che annuncia all'utente lo stato del caricamento. In questo caso queste sezioni sono utili nel momento della ricerca con testo e filtri (query verso API esterne).

8. Comunicazione dello stato (aria-checked, aria-expanded, aria-selected)


Gli screen reader dipendono dagli attributi di stato espliciti (non dalle classi CSS o dal colore visivo) per comunicare cosa è attualmente selezionato o espanso.
aria-checked sulle stelle di valutazione, aria-expanded sui pulsanti delle categorie accordion in una eventuale modale, comunicano i cambiamenti dinamici dell'interfaccia senza richiedere la vista.


9. Relazione controllo–pannello (aria-controls)


aria-controls collega un pulsante di attivazione alla regione che mostra/nasconde, permettendo agli screen reader di navigare direttamente dal controllo al pannello di destinazione.


10. Nascondere il contenuto decorativo (aria-hidden="true", alt="")


Immagini decorative, icon font ed SVG puramente visivi aggiungono rumore quando vengono letti ad alta voce.
aria-hidden="true" rimuove completamente un elemento dall'albero di accessibilità; alt=""su un <img> lo marca come decorativo in modo che venga saltato.
Può essere applicato per esempio, ad un footer, alle icone spinner e agli SVG decorativi.


11. Inertness dello sfondo (attributo :inert)

Quando una modale è aperta, tutto il contenuto dietro di essa deve essere reso non interattivo.
L'attributo HTML inert disabilita focus, eventi del puntatore e visibilità ARIA su un sottoalbero in una sola volta, impedendo agli utenti screen reader di uscire accidentalmente dalla modale.

Esempio d'uso di inert. Quando la modale è aperta, il contenuto di questo div è bloccato.

12. aria-checked esclusivo (semantica del gruppo radio)

In un gruppo a scelta singola (valutazione a stelle), solo l'opzione selezionata deve avere aria-checked="true".
Impostare tutte le stelle precedenti a true (logica cumulativa) fa sì che lo screen reader annunci più opzioni selezionate, creando ambiguità semantica su cosa sia stato effettivamente scelto.


13. Gerarchia degli heading e struttura dei landmark


Gli utenti screen reader navigano i documenti tramite livelli di heading (<h1><h6>) e ruoli landmark (<main>, <nav>, <header>).
Gerarchie di heading mancanti o piatte (es. titoli di sezione come semplici <div>) rendono la struttura della pagina invisibile nella navigazione per titoli.


14. Testo alternativo per le immagini (attributo alt)


Ogni immagine informativa deve avere una descrizione alt significativa.
Quando le immagini sono il mezzo principale per distinguere gli elementi (es. foto di specifici elementi nella schermata di selezione), un alt mancante o nullo rende quegli elementi completamente inaccessibili agli utenti non vedenti.



Un'ancora "Salta al contenuto principale" visivamente nascosta in cima a ogni pagina permette agli utenti di tastiera e screen reader di bypassare gli elementi di navigazione ripetuti (header, menu) e raggiungere direttamente il contenuto principale della pagina, evitando di dover fare Tab su decine di elementi ad ogni caricamento.


16. Contenuto testuale coerente e pronunciabile


Nomi come "Selettore2" o "Pulsante3" (senza spazio) vengono letti dai motori text-to-speech come un unico token, producendo una pronuncia innaturale o errata.
Una nomenclatura coerente e con spazi ("Selettore 2", "Pulsante 3") garantisce che il TTS li riproduca in modo intelligibile.


17. aria-atomic sugli annunci


Combinato con aria-live, aria-atomic="true" garantisce che l'intero testo di una live region venga riannunciato come un'unica unità quando una qualsiasi parte cambia, invece di annunciare solo il frammento modificato.
Utilizzato ad esempio sui contatori dei risultati della ricerca per annunciare il messaggio completo.


18. Etichettatura di mappe e widget complessi


Widget interattivi o informativi come le mappe Leaflet non hanno semantica nativa.
Necessitano di un aria-label esplicito che ne descriva lo scopo e, dove possibile, di un'alternativa testuale non visiva (coordinate, indirizzo) affinché le informazioni che trasmettono siano accessibili senza la vista.

Esempio d'uso dell'alt su un componente LMap. Di default la mappa è ritenuta non accessibile, motivo per il cui l'alt può diventare utile per lo screen reader.

That's all Folks!

@Daniele Melloni - May 2026

Read more