Normative · ARIA

Ruolo Widget

combobox

Contrassegna un campo di testo abbinato a un elenco popup di valori — utilizzato per il completamento automatico, la ricerca predittiva e i select personalizzati. L'elemento nativo <select> copre la selezione singola; usare role="combobox" solo quando servono filtro, rendering personalizzato o suggerimenti remoti.

Quando utilizzarlo

Utilizzare <select> quando la scelta proviene da un elenco breve e fisso e l’utente non ha bisogno di filtrare. L’elemento nativo include picker ottimizzati per dispositivi mobili, supporto completo da tastiera e nessun JavaScript.

role="combobox" è indicato per i casi che il nativo non può gestire:

  • Completamento automatico con filtro (ricerca di città, menzione di un utente).
  • Suggerimenti recuperati da un’API remota.
  • Elementi visualizzati con contenuto ricco (avatar, testo secondario).
  • Input con tag in cui è possibile selezionare più valori.

ARIA 1.2 ha modificato significativamente il pattern combobox. Il role va sull’<input>, NON sul wrapper. Il popup è un role="listbox" separato (o tree/grid/dialog) collegato al combobox tramite aria-controls.

Contratto da tastiera e focus

Secondo il pattern APG combobox:

  • Il focus rimane sempre sull’input. Il listbox viene aperto tramite aria-expanded="true" e l’opzione attiva è tracciata tramite aria-activedescendant, NON spostando il focus.
  • La freccia giù apre il popup e sposta l’opzione attiva al primo elemento.
  • Le frecce su/giù spostano l’opzione attiva all’interno del popup.
  • Enter seleziona l’opzione attiva e chiude il popup.
  • Escape chiude il popup; un secondo Escape svuota l’input.
  • La digitazione filtra l’elenco (quando aria-autocomplete="list" o "both").

Impostare aria-autocomplete su "none", "inline", "list" o "both" per descrivere il comportamento dei suggerimenti.

Errori comuni

  • Posizionare role="combobox" sul wrapper anziché sull’<input> (pattern precedente ad ARIA 1.2). I moderni screen reader si aspettano il role sull’elemento modificabile.
  • Spostare il focus DOM nel listbox alla pressione della freccia giù. L’APG richiede aria-activedescendant; spostare il focus interrompe la digitazione.
  • aria-expanded bloccato su "false" anche quando il popup è visibile.
  • Listbox presente nel DOM ma mai collegato tramite aria-controls.
  • Filtrare l’elenco lasciando aria-activedescendant puntato su un elemento che non esiste più.

Esempio

<label for="city">Città</label>
<input
  id="city"
  type="text"
  role="combobox"
  aria-controls="cityList"
  aria-expanded="false"
  aria-autocomplete="list"
  aria-activedescendant=""
>
<ul id="cityList" role="listbox" hidden>
  <li id="city-1" role="option">London</li>
  <li id="city-2" role="option">Lisbon</li>
  <li id="city-3" role="option">Ljubljana</li>
</ul>