Normative · ARIA

Ruolo Widget

radio

Contrassegna un elemento come opzione singola in un gruppo mutuamente esclusivo. Un radio deve trovarsi all'interno di un radiogroup (o di un fieldset nativo). Si usi <input type="radio"> in via prioritaria; si ricorra a role="radio" solo quando l'input nativo non è praticabile.

Quando utilizzarlo

Si usi <input type="radio"> raggruppato da un attributo name condiviso, racchiuso in <fieldset> con un <legend>. L’elemento nativo gestisce gratuitamente la navigazione con i tasti freccia, il roving tabindex, la selezione esclusiva e l’invio del modulo.

role="radio" è destinato ai componenti personalizzati — controlli segmentati, widget di valutazione, selettori tematici — dove non è possibile usare l’input nativo. Un elemento role="radio" DEVE avere un genitore (o un target aria-owns) con role="radiogroup".

Contratto tastiera + focus

Secondo il pattern APG radio group:

  • Tab sposta il focus nel gruppo, sul radio selezionato (o sul primo radio se nessuno è selezionato).
  • Tab sposta il focus FUORI dal gruppo. Tab NON cicla tra i radio.
  • I tasti freccia (Su/Giù o Sinistra/Destra) spostano il focus al radio successivo/precedente E lo selezionano. Questo comportamento è insolito — la maggior parte dei widget separa il focus dalla selezione, ma i radio li accoppia.
  • Space seleziona il radio con il focus se non è già selezionato.

Si usi un roving tabindex: solo il radio attualmente selezionato ha tabindex="0", gli altri hanno tabindex="-1".

Errori comuni

  • Radio personalizzati in cui Tab cicla tra ogni opzione (invece dei tasti freccia). Viola il modello di interazione standard dei radio.
  • role="radio" senza un role="radiogroup" contenitore. Gli screen reader non possono annunciare l’etichetta del gruppo né la posizione nell’insieme.
  • Tutti i radio con tabindex="0" — ogni radio entra nell’ordine di tabulazione, moltiplicando le sequenze di tasti.
  • aria-checked assente al rendering iniziale.
  • Radio personalizzati che si deselezionano se premuti di nuovo. Un radio è esclusivo: una volta selezionato, l’unico modo per deselezionarlo è selezionarne un altro nel gruppo.

Esempio

<!-- Preferito -->
<fieldset>
  <legend>Frequenza delle notifiche</legend>
  <label><input type="radio" name="freq" value="daily" checked> Giornaliera</label>
  <label><input type="radio" name="freq" value="weekly"> Settimanale</label>
  <label><input type="radio" name="freq" value="never"> Mai</label>
</fieldset>

<!-- Gruppo radio personalizzato -->
<div role="radiogroup" aria-labelledby="freqLabel">
  <span id="freqLabel">Frequenza delle notifiche</span>
  <div role="radio" aria-checked="true"  tabindex="0">Giornaliera</div>
  <div role="radio" aria-checked="false" tabindex="-1">Settimanale</div>
  <div role="radio" aria-checked="false" tabindex="-1">Mai</div>
</div>