Normativas · ARIA

Rol Control

checkbox

Marca un elemento como casilla de verificación de dos o tres estados. Se recomienda usar <input type="checkbox"> en primer lugar; recurra a role="checkbox" solo cuando no pueda utilizar el elemento nativo — por ejemplo, al construir un control de tres estados que deba mostrar un valor mixto.

Cuándo usar

Use <input type="checkbox">. El elemento nativo proporciona foco, activación con Espacio, la pseudoclase :checked, envío de formularios y la propiedad JS indeterminate para el estado triestado. role="checkbox" existe para dos casos:

  • Necesita una casilla de verificación triestado expuesta como aria-checked="mixed" (un «seleccionar todo» que refleja el estado de los elementos secundarios).
  • Un sistema de diseño incluye un componente de casilla personalizado que no se puede reemplazar.

Si implementa role="checkbox" en un elemento que no es un <input>, debe establecer aria-checked (es obligatorio), gestionar tabindex="0" y manejar el evento keydown para Espacio.

Contrato de teclado y foco

Según el patrón de casilla de verificación de la APG:

  • Tab mueve el foco a la casilla de verificación.
  • Espacio alterna aria-checked entre "true" y "false" (y "mixed" en el caso triestado).
  • Enter NO activa una casilla de verificación — solo Espacio. (Los elementos nativos también ignoran Enter en la mayoría de los navegadores.)

El foco permanece en la casilla de verificación después de la activación.

Errores frecuentes

  • role="checkbox" sin atributo aria-checked establecido. El estado es obligatorio desde el momento en que el elemento está en el DOM.
  • Usar aria-checked="true" solo como gancho de clase — actualizando el aspecto visual pero sin actualizar nunca el atributo al hacer clic.
  • Casillas personalizadas que responden al clic pero no a Espacio.
  • Anidar un <input> nativo dentro de un <div role="checkbox"> — la semántica duplicada confunde a los lectores de pantalla.
  • Controles triestado que recorren Espacio en el ciclo false → true → mixed → false. La APG especifica false → true → false; mixed lo establece la página mediante programación, no el usuario.

Ejemplo

<!-- Recomendado -->
<label>
  <input type="checkbox" name="terms" required>
  Acepto los términos y condiciones
</label>

<!-- «Seleccionar todo» personalizado triestado -->
<div
  role="checkbox"
  tabindex="0"
  aria-checked="mixed"
  aria-labelledby="selectAllLabel"
>
</div>
<span id="selectAllLabel">Select all rows</span>