Come creare popup e modali accessibili
Quando navighiamo un sito web ci capita sicuramente di incontrare dei popup, cioè delle finestre che appaiono in sovraimpressione all’interno di una pagina web, che ci comunicano qualche informazione. Un esempio classico è il banner di consenso sui cookie, che sia custom o implementato attraverso piattaforme quali Iubenda o Cookiebot.
Un altro esempio molto utilizzato anche dalle Pubbliche Amministrazioni è quello di avere una finestra di ricerca nel sito che appare quando si clicca l’icona con la lente di ingrandimento.
Tabella dei contenuti
I modali e le tecnologie assistive
Anche chiamate “modali”, queste finestre hanno sicuramente l’utilità di attirare l’attenzione dell’utente. Tuttavia è bene comprendere che possono diventare piuttosto fastidiose per l’utente ipovedente o che sta visitando il sito tramite tecnologie assistive come gli screen reader.
Molto spesso sono poste in cima nella gerarchia HTML, rischiando quindi di venire lette come primo contenuto dai software di lettura schermo. In altri casi, non vengono lette del tutto perché posizionate in fondo all’HTML oppure non vengono annunciate quando appaiono. Infine, potrebbero apparire in un momento in cui l’utente è concentrato su altro e la sua lettura viene interrotta da un contenuto che viene letto improvvisamente.
Dobbiamo quindi capire meglio come rendere questi componenti il più possibile accessibili.
Le linee guida WAI-ARIA offrono alcuni casi d’uso utili per capire come impostare una modale:
Questi esempi sono già piuttosto dettagliati, ma proviamo ad analizzare meglio i punti principali dal lato tecnico, e vediamo quali sono gli aspetti più interessanti da tenere in considerazione per l’accessibilità.
Esempio pratico: date picker e calendario
Iniziamo dal date picker, che è un caso più particolare ma utile da conoscere:
- Abbiamo un <button> che aziona la modale tramite Javascript. Qui non l’hanno inserito, ma potrebbe aver senso aggiungere anche gli attributi aria-expanded e aria-controls che abbiamo visto in altri casi precedenti. Il “nome accessibile” del button, cioè il testo che viene letto dalle tecnologie assistive, è impostato tramite aria-label in “Choose date”, e viene modificato in Javascript quando viene selezionata una data dal calendario
- La modale che viene aperta è un <div> con role=”dialog” (ancora meglio sarebbe usare il tag HTML <dialog>) e usa l’attributo aria-modal=”true”
- I pulsanti “Esc” o “Invio” permettono di chiudere la modale
- Il tag <input> della data è associato a un testo tramite aria-describedby, così che le tecnologie assistive possano leggere questo testo per aiutare l’utente a comprendere lo scòpo del campo: “date format: mm/dd/yyyy”
- La parte iniziale (header) del calendario contiene dei button per selezionare mese e anno precedenti e successivi, inoltre contiene un h2 con aria-live=”polite” che comunica alle tecnologie assistive l’eventuale cambiamento del testo, ad esempio quando passiamo da “Agosto 2024” a “Settembre 2024” questo verrà “annunciato” dagli screen reader e quindi comunicato all’utente
- Le celle contenenti i nomi abbreviati dei giorni sono dei tag <th> che usano l’attributo “abbr” per indicare il testo completo, lo stesso risultato si potrebbe ottenere usando all’interno del <th> il tag <abbr> con l’attributo title
- Il focus e l’hover dei vari elementi del calendario fanno uso della proprietà CSS “border” per rendere visibile l’effetto e far capire all’utente in modo più chiaro quale elemento è stato selezionato (questo riguarda anche il criterio 2.4.7 Focus visibile)
- Da notare anche l’uso del tabindex nei tag <td> del calendario: è impostato a -1 su tutti i <td> tranne quello selezionato, che prende il valore di 0. Cambiando la data usando le frecce direzionali, la cella selezionata passa da un tabindex=”-1” a tabindex=”0”. In effetti, le celle che usano il valore -1 non sono raggiungibili usando il tasto Tabulazione (Tab)
- Il testo presente in fondo al calendario fa uso di aria-live: <div class=”dialog-message” aria-live=”polite”>, in questo modo, quando il calendario viene aperto, viene letto il testo che informa l’utente della possibilità di cambiare le date usando le frecce direzionali
L’uso di aria-live
Una nota importante sull’uso dell’attributo aria-live: il suo valore può essere impostato in “polite”, “assertive” o “off”. Generalmente, si raccomanda di impostarlo su polite, e quasi mai su assertive. Quest’ultimo valore infatti è da utilizzare solo nei casi in cui è molto importante interrompere l’azione dell’utente per catturare la sua attenzione.
Supponiamo che l’utente stia ascoltando il testo di un paragrafo che viene letto dallo screen reader. Una sezione che usa “assertive” viene modificata dinamicamente in Javascript (anche senza che l’utente abbia fatto alcunché) e questo cambiamento verrà immediatamente annunciato dal lettore di schermo, che quindi interrompe la lettura del paragrafo per leggere il testo modificato. Un esempio può essere un carosello di immagini che ogni 10 secondi cambia slide e presenta un nuovo testo. Parleremo meglio dei caroselli successivamente, ma in un caso di quel genere l’utente potrebbe trovare molto fastidiosa l’interruzione non prevista.
Esempio pratico: modale dialog classico
Ora passiamo ai punti più importanti riguardanti l’esempio di modale “dialog” più classico, il codice al momento è presente su Codepen:
- Il focus iniziale viene impostato sul primo input
- Quando la modale viene chiusa il focus viene riportato sul pulsante di apertura della modale (“Add delivery address”)
- Quando clicchiamo su “Verify Address”, il focus viene impostato sul primo paragrafo, questo perché il primo “elemento focalizzabile” è in fondo al testo ed è un link, l’esempio è stato fatto così appositamente per mostrare questo caso particolare
- Quando clicchiamo su “Add” appare una nuova modale “Address Added” e qui il focus iniziale viene impostato sul pulsante “OK” per permettere la chiusura immediata della finestra
Il codice Javascript usato è piuttosto complesso e probabilmente poco utilizzabile in un caso reale, se non altro per questioni di tempo di lavoro, che si traduce in maggiori risorse economiche. Il mio suggerimento è di fare quello che possiamo, in genere non è necessario raggiungere la perfezione, che può richiedere un onere sproporzionato.
Esempio pratico: modale alert dialog
Infine prendiamo in considerazione l’esempio della modale “alert dialog” più semplice:
- Il <div> che contiene la modale usa il role=”alertdialog”, inoltre usa aria-modal=”true” e aria-labelledby che indica qual è il “nome accessibile” della modale, cioè il testo che viene letto dalle tecnologie assistive
- Il focus iniziale viene impostato sul pulsante “No”, che è il primo “elemento focalizzabile” ed è anche l’azione meno distruttiva, e previene un possibile errore involontario da parte dell’utente. Pensiamo, in un altro caso, a una azione che se attivata per errore elimina il record del database che riguarda un utente (Una azione “cancella utente” con pulsanti “Conferma” e “Annulla”, il focus dovrebbe andare inizialmente su “Annulla” per evitare una conferma involontaria)
- Quando i pulsanti sono disabilitati, viene usato solo l’attributo aria-disabled ma non l’attributo disabled, questo per mantenere attiva la possibilità di raggiungere i pulsanti tramite tasto Tabulazione
Conclusioni
Ci tengo anche a fare un appunto sugli esempi visti finora e che è in linea con quanto detto prima sull’onere spoporzionato: per mia esperienza, rendere 100% accessibile ogni componente è quasi impossibile, ci sono troppi criteri da ricordare e da tenere a mente, e ogni guida riporta delle osservazioni diverse, così come ogni consulente potrebbe interpretare le linee guida in modo diverso.
Ad esempio, sia per esigenze grafiche e sia perché ci è molto difficile rendercene conto in fase di sviluppo, può capitare di dimenticarsi di impostare l’attributo aria-live dove necessario, per fare in modo che la tecnologia assistiva comunichi all’utente il cambiamento di un contenuto. Oppure, l’uso di aria-describedby in molti casi non è richiesto e può anche essere omesso, risulta utile come “qualcosa in più” per rendere il componente il più accessibile possibile.
Quello che posso consigliare, in linea generale, è di fare quello che si può per raggiungere un buon livello di accessibilità. Usiamo i tool automatici, che abbiamo visto in precedenza, per aiutarci nella scansione e nella correzione degli errori. Se possibile, chiediamo un parere ad altri colleghi che si occupano di accessibilità, o affidiamoci a partner esterni per l’analisi di accessibilità.
In fase di analisi e verifica dei requisiti di accessibilità, sicuramente non tutto potrà venire a galla, e cercare l’ago nel pagliaio può richiedere di investire centinaia di ore di lavoro e quindi può far lievitare il costo economico, cosa che le Pubbliche Amministrazioni in particolare non possono permettersi. Dobbiamo quindi conformarci e adattarci al budget disponibile, proviamo a lavorare nel modo migliore possibile ma senza ricercare la perfezione.
Link utili
- WAI: Modal Dialog Example
- WAI: Date Picker Dialog Example
- WAI: Alert Dialog Example
- MDN: aria-live
- W3Schools: attribute abbr for th
- MDN: abbr tag with expansion
- AGID: onere sproporzionato
- MDN: alertdialog ARIA role
- MDN: <dialog> HTML tag
- MDN: aria-modal
- MDN: aria-labelledby
- MDN: aria-disabled
- MDN: disabled attribute