checkbox
Contrassegna un elemento come checkbox a due o tre stati. Utilizzare prima <input type="checkbox">; ricorrere a role="checkbox" soltanto quando non è possibile usare l'input nativo — ad esempio per costruire un controllo tri-stato che deve mostrare un valore misto.
Quando utilizzarlo
Utilizzare <input type="checkbox">. L’elemento nativo fornisce focus, attivazione con Space, la pseudo-classe :checked, l’invio del form e la proprietà JS indeterminate per il tri-stato. role="checkbox" esiste per due casi:
- Si necessita di una checkbox tri-stato esposta come
aria-checked="mixed"(un «seleziona tutto» che riflette lo stato dei figli). - Un design system distribuisce un componente checkbox personalizzato che non è possibile sostituire.
Se si implementa role="checkbox" su un elemento che non è un input, è necessario impostare aria-checked (attributo obbligatorio), gestire tabindex="0" e intercettare il tasto Space tramite keydown.
Contratto da tastiera e focus
Secondo il pattern APG checkbox:
- Tab sposta il focus sulla checkbox.
- Space alterna
aria-checkedtra"true"e"false"(e"mixed"per il tri-stato). - Enter NON attiva una checkbox — solo Space. (Anche gli input nativi ignorano Enter nella maggior parte dei browser.)
Il focus rimane sulla checkbox dopo l’attivazione.
Errori comuni
role="checkbox"senza l’attributoaria-checkedimpostato. Lo stato è obbligatorio dal momento in cui l’elemento è presente nel DOM.- Utilizzare
aria-checked="true"solo come hook di classe — aggiornare l’aspetto visivo senza mai aggiornare l’attributo al click. - Checkbox personalizzate che rispondono al click ma non a Space.
- Racchiudere un
<input>nativo all’interno di un<div role="checkbox">— la semantica duplicata confonde gli screen reader. - Controlli tri-stato in cui Space cicla tra false → true → mixed → false. L’APG specifica false → true → false; il valore mixed è impostato programmaticamente dalla pagina, non dall’utente.
Esempio
<!-- Preferito -->
<label>
<input type="checkbox" name="terms" required>
Accetto i termini e le condizioni
</label>
<!-- "Seleziona tutto" personalizzato tri-stato -->
<div
role="checkbox"
tabindex="0"
aria-checked="mixed"
aria-labelledby="selectAllLabel"
>
</div>
<span id="selectAllLabel">Seleziona tutte le righe</span>