Skip to main content
Validación HTML

Un elemento con “role=tab” debe estar contenido en, o ser propiedad de, un elemento con “role=tablist”.

Acerca de este problema HTML

La especificación WAI-ARIA define un modelo de propiedad estricto para los roles relacionados con pestañas. Un elemento con role="tab" controla la visibilidad de un elemento asociado role="tabpanel", y se espera que las pestañas estén agrupadas dentro de un tablist. Esta relación es cómo las tecnologías de asistencia como los lectores de pantalla entienden y comunican el patrón de interfaz de pestañas a los usuarios — por ejemplo, anunciando “pestaña 2 de 4” cuando el foco se mueve entre pestañas.

Cuando una tab no está contenida en o es propiedad de un tablist, los lectores de pantalla no pueden determinar cuántas pestañas existen en el grupo, qué pestaña está actualmente seleccionada, o cómo navegar entre ellas. Esto rompe fundamentalmente la accesibilidad de la interfaz de pestañas, haciéndola confusa o inutilizable para personas que dependen de tecnologías de asistencia.

Hay dos maneras de establecer la relación requerida:

  1. Contención directa: Coloca los elementos role="tab" como hijos directos del elemento role="tablist". Este es el enfoque más común y directo.
  2. Usando aria-owns: Si la estructura DOM impide el anidamiento directo, añade aria-owns al elemento tablist con una lista separada por espacios de valores id que referencien cada pestaña. Esto le dice a las tecnologías de asistencia que el tablist es propietario de esas pestañas aunque no sean hijos directos en el DOM.

Ejemplos

Incorrecto: pestaña fuera de un tablist

En este ejemplo, los botones role="tab" son hermanos del tablist en lugar de hijos de él, lo que desencadena el error de validación.

<div class="tabs">
  <div role="tablist" aria-label="Sample Tabs"></div>
  <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
    First Tab
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">
    Second Tab
  </button>
</div>

Correcto: pestañas como hijos directos de tablist

La solución más simple es colocar los elementos role="tab" directamente dentro del elemento role="tablist".

<div class="tabs">
  <div role="tablist" aria-label="Sample Tabs">
    <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
      First Tab
    </button>
    <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
      Second Tab
    </button>
  </div>
  <div id="panel-1" role="tabpanel" tabindex="0" aria-labelledby="tab-1">
    <p>Content for the first panel</p>
  </div>
  <div id="panel-2" role="tabpanel" tabindex="0" aria-labelledby="tab-2" hidden>
    <p>Content for the second panel</p>
  </div>
</div>

Correcto: usando aria-owns cuando el anidamiento DOM no es posible

Si tu diseño o framework hace difícil anidar las pestañas directamente dentro del tablist, puedes usar aria-owns para establecer la relación programáticamente.

<div class="tabs">
  <div role="tablist" aria-label="Sample Tabs" aria-owns="tab-1 tab-2"></div>
  <div class="tab-wrapper">
    <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
      First Tab
    </button>
    <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
      Second Tab
    </button>
  </div>
  <div id="panel-1" role="tabpanel" tabindex="0" aria-labelledby="tab-1">
    <p>Content for the first panel</p>
  </div>
  <div id="panel-2" role="tabpanel" tabindex="0" aria-labelledby="tab-2" hidden>
    <p>Content for the second panel</p>
  </div>
</div>

Notas adicionales

  • Cada elemento role="tab" debe usar aria-selected para indicar qué pestaña está activa ("true") y cuáles no ("false").
  • Usa aria-controls en cada pestaña para referenciar el id de su tabpanel asociado.
  • Usa aria-labelledby en cada tabpanel para apuntar de vuelta a su pestaña controladora.
  • Establece tabindex="0" en la pestaña activa y tabindex="-1" en las pestañas inactivas para soportar la navegación por teclado con las teclas de flecha dentro del tablist.
  • Incluye siempre un aria-label o aria-labelledby en el tablist para darle un nombre accesible.

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.