Vai al contenuto

WAI-ARIA, la tecnologia assistita nei siti web

La Web Accessibility Initiative — Accessible Rich Internet Applications (WAI-ARIA) è una specifica tecnica che fornisce indicazioni su come migliorare l’accessibilità delle applicazioni web. Laddove le Linee guida per l’accessibilità dei contenuti Web (WCAG) si concentrano maggiormente sui contenuti Web statici, WAI-ARIA si concentra sul rendere le interazioni più accessibili.

Quando le app Web hanno iniziato a diventare più complesse e dinamiche, le interazioni sul web sono diventate notoriamente poco “accessibili”. Spesso fanno parte di funzioni più critiche come presentare una domanda di lavoro, acquistare da un negozio online o prenotare una visita medica.

L’HTML non fornisce la possibilità di creare contenuti dinamici o controlli avanzati per l’interfaccia utente, ma consente l’inclusione di script lato client per creare controlli per l’interfaccia utente che non possono essere creati con il solo HTML. Gli script vengono ormai anche utilizzati per aggiornare sezioni di una pagina senza richiederne una nuova al web server, rendendo queste pagine delle Rich Internet Applications. Questi controlli lato utente e l’aggiornamento dinamico dei contenuti sono spesso non accessibili per utenti con disabilità, specialmente per coloro che utilizzano screen reader e utenti che non possono utilizzare il mouse o altri dispositivi di puntamento.

WAI-ARIA descrive come aggiungere una semantica o altri metadati al contenuto HTML allo scopo di rendere i controlli lato utente e i contenuti dinamici più accessibili. Ci sono tre caratteristiche principali definite nelle specifiche:

  • Ruoli: definiscono cosa è o cosa fa un elemento. Molti di questi sono cosiddetti ruoli di riferimento, che duplicano ampiamente il valore semantico degli elementi strutturali, come role=”navigation” (<nav>) o role=”complementary”(<aside>). Alcuni altri ruoli descrivono diverse strutture di pagina, come role=”banner”, role=”search”, role=”tablist” e role=”tabpanel”, che si trovano comunemente nelle interfacce utente.
  • Proprietà: Definiscono le proprietà degli elementi, che possono essere utilizzate per dare loro un significato o una semantica extra. Ad esempio, aria-required=”true” specifica che un modulo di input deve essere compilato per essere valido, mentre aria-labelledby=”label” consente di inserire un ID su un elemento, quindi fare riferimento ad esso come etichetta per qualsiasi altra cosa sulla pagina, inclusi più elementi, che è non è possibile utilizzare con <label for=”input”>. Ad esempio, possiamo specificare aria-labelledby come alternativa al testo alternativo dell’immagine: specificare le informazioni esistenti sulla pagina come testo alternativo di un’immagine, piuttosto che ripeterlo all’interno dell’attributo alt.
  • Stati: proprietà speciali che definiscono le condizioni correnti degli elementi, ad esempio aria-disabled=”true”, che specifica a un’utilità per la lettura dello schermo che un input del modulo è attualmente disabilitato. Gli stati differiscono dalle proprietà in quanto le proprietà non cambiano durante il ciclo di vita di un’app, mentre gli stati possono cambiare, generalmente a livello di codice tramite JavaScript.

HTML

Quando usiamo elementi HTML come input, selecte button, le informazioni sull’elemento vengono passate al DOM (Document Object Model) e in un albero di accessibilità. I browser creano l’albero di accessibilità basato sull’albero DOM, che viene utilizzato dalle API di accessibilità specifiche della piattaforma per fornire una rappresentazione che può essere compresa dalle tecnologie assistive. Ad esempio uno screen reader può comprendere:

  • che tipo di elemento è selezionando il suo ruolo, ad esempio checkbox
  • in quale stato si trova l’elemento, ad esempio, selezionato/non verificato
  • il nome dell’elemento, ad es. “Iscriviti alla nostra newsletter”

L’altra cosa che otteniamo quando usiamo gli elementi HTML è l’interattività della tastiera. Ad esempio, una casella di controllo può essere focalizzata utilizzando il tasto Tab e selezionata utilizzando la barra spaziatrice (le interazioni specifiche possono variare in base al browser e al sistema operativo, ma il punto è che sono disponibili e standardizzate su tutti i siti Web quando si utilizzano elementi HTML).

Quando non si utilizza l’HTML puro per l’interazione, è necessario svolgere un lavoro aggiuntivo per fornire informazioni sull’elemento e creare interattività della tastiera per gli utenti di tecnologie assistive. È qui che entra in gioco ARIA.

ARIA

Possiamo usare ARIA per passare informazioni all’albero di accessibilità. I ruoli e gli attributi di ARIA non includono alcuna interattività della tastiera. L’aggiunta role=”button” a un tag <div> non risponde quando si preme il tasto INVIO, che è necessario creare utilizzando JavaScript o un’altra lingua. Tuttavia, la ARIA Authoring Practices Guide include un elenco di quale interattività della tastiera dovrebbe essere aggiunta a vari componenti come fisarmoniche, pulsanti, caroselli, ecc.

Ruoli

Prendiamo in esame questo pezzo di codice. Che cosa mi rappresenta?

<div className="dd-wrapper"> 
  <div className="dd-header"> 
    <div className="dd-header-title"></div> 
  </div> 
  <div className="dd-list"> 
    <button className="dd-list-item"></button> 
    <button className="dd-list-item"></button> 
    <button className="dd-list-item"></button> 
  </div> 
</div>

Il fatto che l’elemento rappresentato dal codice sia completamente irriconoscibile è esattamente il problema che avrebbe qualsiasi tecnologia assistiva: non può dire all’utente di cosa si tratta o come interagire con esso perché non esiste un ruolo ARIA. Quindi possiamo aggiungere l’attributo role, per meglio chiarire la rappresentazione del blocco HTML.

<div className="dd-wrapper" role="listbox">

Una listbox è una specie di select che un utente di screen reader potrebbe riconoscere e sapere come interagire.  Quindi un ruolo dice al dispositivo di tecnologia assistita di cosa si tratta. Il ruolo va scelto con consapevolezza, in modo che corrisponda alla funzione del componente che stiamo costruendo.

Un’altra cosa da  sapere sui ruoli ARIA è che sovrascrivono il ruolo intrinseco di un elemento HTML. Quindi:

<img role="button">

non è più un’immagine ma un pulsante. Ci sono pochissime ragioni per farlo solitamente si evita di sovrascrivere i ruoli HTML esistenti, per non generare confusione. Ci sono molti altri modi per raggiungere questo obiettivo che hanno più senso dal punto di vista dell’accessibilità e della robustezza del codice:

<button><img src="image.png" alt="Print" /></button> 
<input type="image" src="image.png" alt="Print" /> 
<button style="background: url(image.png)" />Print</button>

In sintesi, se stiamo sviluppando qualcosa che non ha un tag HTML semantico che lo descriva (cioè, qualsiasi cosa interattiva creata usando <div> <span>), deve avere un ruolo ARIA in modo che la tecnologia assistita possa riconoscere di cosa si tratta.

Stati e Proprietà (ovvero gli Attributi ARIA)

Oltre a sapere cos’è un elemento, se ha uno stato (ad esempio, hidden, disabled, invalid, readonly, selected e così via) o se cambia stato (ad esempio, checked/ not checked, open/ closed e così via), è necessario dire agli utenti di tecnologie assistite qual è lo stato attuale è e il suo nuovo stato ogni volta che cambia. La differenza tra stati e proprietà non è molto chiara o importante, quindi chiamiamoli semplicemente attributi.

Ecco alcuni degli attributi ARIA più comuni che potremmo dover utilizzare:

  • aria-checked
    Viene utilizzato con =”true”=”false” per indicare se le caselle di controllo e i pulsanti di opzione sono attualmente selezionati o meno.
  • aria-current
    Viene utilizzato con =”true”=”false” per indicare la pagina corrente all’interno di breadcrumb o impaginazione.
  • aria-describedby
    Viene utilizzato con l’id di un elemento per aggiungere ulteriori informazioni a un campo modulo oltre alla relativa etichetta. aria-describedby può essere utilizzato per fornire esempi del formato richiesto per un campo, ad esempio una data, o per aggiungere un messaggio di errore a un campo modulo.

    <label for="birthday">Birthday</label> 
    <input type="text" id="birthday" aria-describedby="date-format"> 
    <span id="date-format">MM-DD-YYYY</span>
  • aria-expanded
    Viene utilizzato con =”true” =”false” per indicare se premendo un pulsante verranno visualizzati più contenuti. Gli esempi includono fisarmoniche e voci di navigazione con sottomenu.

    <button aria-expanded="false">Products</button>

    Ciò indica che il menu Prodotti aprirà un sottomenu (ad esempio di diverse categorie di prodotti). Se dovessi codificarlo in questo modo:

    <a href="/products/">Products</a>

    Stiamo impostando un collegamento e facendo clic su di esso si passerà a una nuova pagina. Se non andrà a una nuova pagina, ma in realtà rimane sulla stessa pagina ma apre un sottomenu, questo è ciò che il pulsante con aria-expanded dice a un utente di tecnologia assistiva. Quella semplice differenza tra <button> e <a> e l’aggiunta di aria-expanded comunica così tanto su come interagire con gli elementi e cosa accadrà quando lo farai.

  • aria-hidden
    Viene utilizzato con =”true”=”false” per nascondere qualcosa che è visibile, ma non si desidera che gli utenti di tecnologie assistite lo sappiano. Da usare con estrema cautela poiché ci sono pochissimi casi in cui non desideriamo che vengano presentate informazioni equivalenti.
  • aria-required
    Viene utilizzato con =”true”=”false” per indicare se un elemento del modulo deve essere compilato prima che il modulo possa essere inviato.

Tutti questi attributi ARIA dicono qualcosa a un utente. aria-checked=”true” in realtà non seleziona una casella di controllo ma dice semplicemente all’utente che la casella di controllo è selezionata. L’eccezione sarebbe aria-hidden=”true” che rimuove un elemento dall’albero di accessibilità, nascondendolo di fatto a chiunque utilizzi la tecnologia assistita che non può vedere.

Gestione Del Focus

Qualsiasi cosa interattiva su un sito Web o un’app Web deve essere in grado di ricevere il focus dal dispositivo di puntamento. Non tutti utilizzeranno mouse, trackpad o touch screen per interagire con i siti. Molte persone usano la tastiera o un dispositivo di tecnologia assistita che emula una tastiera. Ciò significa che per tutto ciò su cui puoi fare clic, dovresti anche essere in grado di utilizzare il tasto Tab o i tasti freccia per raggiungerlo e il tasto INVIO, e talvolta la barra spaziatrice, per selezionarlo.

Ci sono tre concetti da considerare se usiamo <div> <span> per creare elementi interattivi:

  1. È necessario aggiungere al primo elemento tabindex=”0″ in modo che una tastiera o un emulatore possa concentrarsi su di esso
  2. Per tutto ciò che accetta l’input da tastiera, è necessario aggiungere un listener di eventi per ascoltare la pressione dei tasti
  3. È necessario aggiungere il ruolo appropriato in modo lo screen reader possa identificare l’elemento che hai creato

I controlli HTML nativi accettano già lo stato attivo e l’input della tastiera e hanno ruoli intrinseci. L’uso di tabindex e role viene quindi usato per la costruzione di elementi personalizzati e non semantici. Notare il tabindex e il ruolo:

<div tabindex="0" role="button" onclick="doSomething();"> 
Cliccami!
</div>

In javascript avremo il seguente script per “ascoltare” la pressione dei tasti:

const ENTER = 13; 
const SPACE = 32; 
// Select your button and store it in ‘myButton’ 
myButton.addEventListener('keydown', function(event) { 
    if (event.keyCode === ENTER || event.keyCode === SPACE) { 
        event.preventDefault(); // Prevents unintentional form submissions, page scrollings, the like 
        doSomething(event); 
    } 
});

Errori Comuni

  • Utilizzo dell’attributo aria-labelledby che fa riferimento a un ID che non esiste
  • Aggiunta di ruoli che duplicano html (ad esempio, in generale, scrivere <button role=”button”> è inutile.)
  • Aggiunta tabindex=”0″ a ogni elemento
  • Utilizzo di ruoli figlio senza ruoli padre (ad esempio, role=”option” deve avere un genitore diretto con attributo role=”listbox”).
  • Usare role=”menu” per la navigazione.
    La navigazione del sito è in realtà un sommario e non un menu. I menu ARIA non sono pensati per essere utilizzati per la navigazione, ma come per i menu in un’applicazione desktop. Invece, usiamo <nav>, mentre i sub-link di navigazione, dovrebbero essere nascosti fino a quando non viene premuto un pulsante per mostrarli.

Come Convalidare ARIA

Esistono numerosi strumenti di tecnologie assistite ARIA che possono essere di supporto agli sviluppatori:

Framework E Librerie Di Componenti

Esistono inoltre delle librerie di componenti ARIA compliant. Tuttavia, l’accessibilità può essere complessa e non tutto ciò che afferma di essere accessibile è veramente accessibile. Il modo migliore per garantire l’accessibilità è testare sempre quello che man mano si sta sviluppando. Alcuni Framework di partenza utili sono:

Conclusione

  1. La prima regola di ARIA è “non usare ARIA”. Un <button> sarà sempre meglio di <div role=”button”>
  2. Secondo, non sovrascrivere la semantica nativa. Invece di <button role=”heading”>, possiamo usare <h3><button></h3>
  3. Terzo, tutti gli elementi interattivi di ARIA devono funzionare con la tastiera
  4. Non utilizzare role=”presentation”aria-hidden=”true” su un elemento focalizzabile. <button role=”presentation”> significa che stiamo nascondendo quel pulsante solo agli utenti ARIA rendendolo inaccessibile
  5. Ultimo ma non meno importante, tutti gli elementi accessibili interattivi devono avere un nome. Ci sono molti modi per farlo, ed eccone alcuni:
    <button>Print</button> (il nome è il nome del pulsante) 
    <div aria-label="Settings"><svg></div> (l'attributo aria-label imposta un nome) 
    
    <div aria-labelledby="myName"> 
    <h1 id="myName">Heading</h1> 
    </div> 
    
    <label for="name">Name</label> 
    <input type="text" id="name" />