aria-activedescendant
Su un widget composito, indica l'ID del discendente attualmente attivo. Il focus DOM rimane sul contenitore mentre un focus virtuale si sposta tra i figli. Alternativa al roving tabindex per listbox, combobox e griglie.
Quando usarlo
Su un widget composito in cui si desidera un unico tab stop ma l’utente deve comunque spostare un’evidenziazione tra molti elementi — ad esempio un input combobox con un popup listbox, una listbox a tab stop singolo, un treegrid, un datagrid. Il focus DOM rimane sull’elemento contenitore (l’input, la listbox, la griglia). Mentre l’utente preme i tasti freccia, occorre aggiornare aria-activedescendant all’ID del figlio appena evidenziato; la tecnologia assistiva lo annuncia come se il focus si fosse spostato lì.
Il pattern alternativo è il roving tabindex: spostare effettivamente il focus DOM e regolare i valori di tabindex. Si sceglie aria-activedescendant quando mantenere il focus del browser sul contenitore semplifica il codice — tipicamente perché il contenitore è anche il punto in cui l’utente digita o a cui sono associati i tasti di scelta rapida.
Come si comporta
Il valore è un singolo ID elemento — mai un elenco. L’elemento referenziato deve essere un discendente del contenitore che possiede l’attributo aria-activedescendant (o appropriato tramite aria-owns). Quando il valore cambia, la posizione del «focus virtuale» nell’albero di accessibilità si sposta su quell’elemento e la tecnologia assistiva ne annuncia l’etichetta, il ruolo e lo stato.
Due aspetti rimangono sotto la responsabilità dello sviluppatore:
- Lo stile visivo. La tecnologia assistiva sa dove si trova il focus virtuale, ma il browser non disegna un anello di focus sul discendente. È necessario aggiungere il proprio CSS di evidenziazione, spesso tramite una classe attivata in sincronia.
- Lo scorrimento. Se il discendente attivo è al di sotto dell’area visibile, occorre portarlo in vista tramite scroll; il browser non lo farà automaticamente.
Quando il popup si chiude o il widget perde il focus, è necessario impostare aria-activedescendant a una stringa vuota o rimuovere l’attributo.
Errori comuni
- Indicare un ID che non è un discendente (e non è appropriato tramite
aria-owns). La tecnologia assistiva ignora il riferimento. - Mescolare i pattern: applicare sia
tabindex="0"al discendente sia impostarearia-activedescendantsul contenitore. Occorre scegliere una sola strategia di focus; usarle entrambe crea conflitti. - Dimenticare di aggiornare l’evidenziazione visiva quando l’attributo cambia — gli utenti vedenti non percepiscono alcuno spostamento mentre gli utenti di tecnologie assistive lo sentono.
- Lasciare un ID non aggiornato dopo che l’opzione è stata rimossa dall’elenco (ad esempio, risultati filtrati in una combobox).
- Aggiornare
aria-activedescendantal passaggio del mouse. L’attributo deve tracciare solo l’elemento attivo tramite tastiera. - Impostarlo su un elemento che non contiene il discendente nell’albero di accessibilità (dimenticando
aria-ownsper una lista portaled).
Esempio
<label for="fruit">Frutto</label>
<input
id="fruit"
role="combobox"
type="text"
aria-controls="fruit-listbox"
aria-expanded="true"
aria-activedescendant="fruit-2"
autocomplete="off"
>
<ul id="fruit-listbox" role="listbox">
<li id="fruit-1" role="option">Mela</li>
<li id="fruit-2" role="option" class="is-active">Banana</li>
<li id="fruit-3" role="option">Ciliegia</li>
</ul>