Normative · ARIA

Ruolo Widget

treeitem

Contrassegna un elemento come nodo all'interno di un albero. Un treeitem può essere espandibile (padre di altri treeitem) o terminale (foglia). Usare solo per navigatori gerarchici — esplora file, organigramma, categorie annidate — che richiedono navigazione a singola tabulazione con frecce direzionali.

Quando utilizzarlo

All’interno di un role="tree", per ogni nodo visibile. Se il nodo ha figli, occorre impostare aria-expanded="true" o "false" e contenere o possedere un role="group" con i treeitem figli. Se il nodo non ha figli, si omette aria-expanded del tutto (NON impostarlo a "false" su una foglia — questo annuncerebbe «compresso» senza nulla da espandere).

Impostare aria-level (profondità con indice 1), aria-posinset (posizione tra i fratelli, con indice 1) e aria-setsize (numero totale di fratelli) su ogni treeitem quando la struttura visiva annidata non può essere dedotta dalla gerarchia del DOM.

Per una navigazione che è sostanzialmente «un elenco di link con sotto-link annidati», <nav> con <ul> annidati e <a> è la scelta più appropriata. Si ricorra al treeview solo quando l’esperienza è un navigatore gerarchico a singola tabulazione.

Contratto da tastiera e focus

Secondo il pattern APG treeview:

  • Tab sposta il focus nell’albero, sul treeitem corrente; Tab lo sposta FUORI.
  • Le frecce Su/Giù spostano il focus tra i nodi visibili (saltando i figli compressi).
  • Freccia Destra: se il nodo è compresso, lo espande; se espanso, sposta il focus al primo figlio.
  • Freccia Sinistra: se il nodo è espanso, lo comprime; se compresso, sposta il focus al nodo padre.
  • Home / End spostano al primo / ultimo nodo visibile.
  • Invio o Spazio attivano (selezionano) l’elemento corrente.
  • Typeahead: digitare una lettera sposta il focus al successivo nodo visibile corrispondente.

Errori comuni

  • aria-expanded="false" su un nodo foglia — annuncia uno stato espandibile fantasma.
  • Tutti i treeitem con tabindex="0". Il pattern prevede una singola tabulazione; solo l’elemento con focus porta tabindex="0".
  • Le frecce Destra/Sinistra usate per «nodo successivo / nodo precedente» anziché per espandere/comprimere.
  • Treeitem figli inseriti direttamente nel <li> padre senza un role="group" che li racchiuda. Gli screen reader non riescono ad annunciare il gruppo come unità.
  • aria-level mancante quando il DOM è piatto (ad esempio quando l’albero è reso con posizionamento assoluto).

Esempio

<ul role="tree" aria-label="Files">
  <li role="treeitem" aria-expanded="true" tabindex="0">
    Documents
    <ul role="group">
      <li role="treeitem" tabindex="-1">Resume.pdf</li>
      <li role="treeitem" aria-expanded="false" tabindex="-1">
        Photos
        <ul role="group">
          <li role="treeitem" tabindex="-1">2025-summer.jpg</li>
        </ul>
      </li>
    </ul>
  </li>
  <li role="treeitem" tabindex="-1">Downloads</li>
</ul>