radio
Marca un elemento como una opción única dentro de un grupo mutuamente excluyente. Un radio debe estar dentro de un radiogroup (o un fieldset nativo). Se recomienda usar <input type="radio"> en primer lugar; solo se debe recurrir a role="radio" cuando el elemento nativo sea imposible de usar.
Cuándo utilizarlo
Se debe usar <input type="radio"> agrupados mediante un atributo name compartido, envueltos en <fieldset> con una <legend>. El elemento nativo gestiona de forma gratuita la navegación con teclas de flecha, el índice de tabulación itinerante, la selección exclusiva y el envío del formulario.
role="radio" está reservado para componentes personalizados —controles segmentados, widgets de valoración, selectores con temas— donde no es posible usar el elemento nativo. Un elemento role="radio" DEBE tener un elemento padre (o un destino aria-owns) con role="radiogroup".
Contrato de teclado y foco
Según el patrón de grupo de radio del APG:
- Tab mueve el foco al interior del grupo, sobre el radio marcado (o el primero si ninguno está marcado).
- Tab mueve el foco FUERA del grupo. Tab NO recorre los radios entre sí.
- Las teclas de flecha (Arriba/Abajo o Izquierda/Derecha) mueven el foco al radio siguiente o anterior Y lo marcan. Esto es inusual: la mayoría de los widgets separan el foco de la selección, pero los radios los vinculan.
- Espacio marca el radio enfocado si aún no está marcado.
Se debe usar un índice de tabulación itinerante: solo el radio actualmente seleccionado tiene tabindex="0"; el resto tiene tabindex="-1".
Errores frecuentes
- Radios personalizados donde Tab recorre cada opción (en lugar de las teclas de flecha). Rompe el modelo de interacción estándar de los radios.
role="radio"sin unrole="radiogroup"envolvente. Los lectores de pantalla no pueden anunciar la etiqueta del grupo ni la posición dentro del conjunto.- Todos los radios con
tabindex="0": cada radio entra en el orden de tabulación, multiplicando las pulsaciones de tecla. aria-checkedausente en el renderizado inicial.- Radios personalizados que se desmarcan al volver a presionarlos. Un radio es exclusivo: una vez marcado, la única forma de desmarcarlo es marcar otro del grupo.
Ejemplo
<!-- Recomendado -->
<fieldset>
<legend>Notification frequency</legend>
<label><input type="radio" name="freq" value="daily" checked> Daily</label>
<label><input type="radio" name="freq" value="weekly"> Weekly</label>
<label><input type="radio" name="freq" value="never"> Never</label>
</fieldset>
<!-- Grupo de radio personalizado -->
<div role="radiogroup" aria-labelledby="freqLabel">
<span id="freqLabel">Notification frequency</span>
<div role="radio" aria-checked="true" tabindex="0">Daily</div>
<div role="radio" aria-checked="false" tabindex="-1">Weekly</div>
<div role="radio" aria-checked="false" tabindex="-1">Never</div>
</div>