Skip to main content
Validación HTML

Un elemento con el atributo “tabindex” no debe aparecer como descendiente de un elemento con el atributo “role=button”.

Acerca de este problema HTML

Cuando un elemento tiene role="button", las tecnologías asistivas lo tratan como un único control interactivo, igual que un <button> nativo. Los usuarios esperan navegar hasta él una sola vez con Tab, y luego activarlo con Enter o Espacio. Si existe un descendiente enfocable (un elemento con tabindex) dentro de ese botón, se crea una segunda parada de tabulación dentro de lo que debería ser un solo control. Esto rompe el modelo de interacción esperado y confunde tanto a usuarios de teclado como a lectores de pantalla.

La especificación WAI-ARIA establece explícitamente que ciertos roles, incluyendo button, no deben contener descendientes interactivos o enfocables. Esto es porque un botón es un widget atómico: representa una acción y debería recibir foco como una sola unidad. Cuando un lector de pantalla encuentra un elemento con role="button", lo anuncia como un botón y espera que el usuario interactúe con él directamente. Un elemento enfocable anidado interrumpe esto al crear un objetivo de foco ambiguo: ¿debería el usuario interactuar con el botón exterior o con el elemento enfocable interior?

Este problema surge comúnmente cuando los desarrolladores envuelven elementos en línea como <span> o <a> con tabindex dentro de un <div role="button">, a menudo para aplicar estilos a partes del botón de forma diferente o para añadir manejadores de clic. El enfoque correcto es asegurar que solo el elemento más externo similar a un botón sea enfocable.

Cómo solucionarlo

  1. Usa un elemento nativo <button>. Esta es siempre la mejor solución. Los botones nativos manejan el foco, la interacción por teclado (activación con Enter y Espacio), y los anuncios de accesibilidad automáticamente, sin necesidad de role o tabindex.

  2. Mueve tabindex al contenedor role="button". Si debes usar role="button" (por ejemplo, cuando un <div> necesita comportarse como un botón debido a restricciones de diseño), coloca tabindex="0" en el contenedor mismo y elimina tabindex de todos los descendientes.

  3. Elimina tabindex de los descendientes. Si el elemento interior realmente no necesita ser independientemente enfocable, simplemente elimina el atributo tabindex de él.

Cuando uses role="button" en un elemento no interactivo, recuerda que también necesitas implementar manejadores de eventos de teclado para Enter y Espacio para replicar completamente el comportamiento de un botón nativo.

Ejemplos

Incorrecto: descendiente enfocable dentro de role="button"

<div role="button">
  <span tabindex="0">Haz clic aquí</span>
</div>

El <span> con tabindex="0" crea un elemento enfocable dentro del contenedor role="button", lo que viola las reglas de autoría de ARIA.

Incorrecto: elemento anchor dentro de role="button"

<div role="button" tabindex="0">
  <a href="/action" tabindex="0">Realizar acción</a>
</div>

Aunque el contenedor mismo es enfocable, el <a> anidado con tabindex también es enfocable, creando dos paradas de tabulación para lo que debería ser un solo control.

Correcto: usa un elemento nativo <button>

<button>Haz clic aquí</button>

Un <button> nativo maneja el foco, eventos de teclado y semántica de accesibilidad automáticamente sin atributos adicionales.

Correcto: mueve tabindex al contenedor role="button"

<div role="button" tabindex="0">
  <span>Haz clic aquí</span>
</div>

El tabindex="0" está en el elemento role="button" mismo, y el <span> interior no es independientemente enfocable.

Correcto: botón nativo con contenido interior estilizado

<button>
  <span class="icon">★</span>
  <span class="label">Favorito</span>
</button>

Aún puedes usar elementos interiores con propósitos de estilo dentro de un <button>, solo no les agregues tabindex. El botón maneja el foco como una sola unidad, y los lectores de pantalla anuncian el contenido de texto combinado.

Encuentra problemas como este automáticamente

Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.

Ayúdanos a mejorar nuestras guías

¿Te ha sido útil esta guía?

¿Listo para validar tus sitios?
Inicia tu prueba gratuita hoy.