Normativas · ARIA

Rol Control

tab

Marca un elemento como una pestaña dentro de una interfaz con pestañas. Una pestaña DEBE residir dentro de un tablist y DEBERÍA referenciar su tabpanel asociado mediante aria-controls. No existe ningún elemento HTML nativo equivalente — las pestañas son un patrón exclusivo de ARIA.

Cuándo utilizarlo

Para representar una pestaña dentro de una barra de pestañas dispuesta horizontal o verticalmente. Una pestaña DEBE ser un hijo directo de un elemento role="tablist" (o estar incluida mediante aria-owns). Cada pestaña DEBE apuntar a su panel asociado mediante aria-controls="<tabpanel-id>". El reciproco aria-labelledby vive en el panel y apunta de vuelta a la pestaña.

Las pestañas son un patrón de aplicación. Si las «pestañas» enlazan realmente a páginas distintas, conviene utilizar <nav> con enlaces <a> — el cambio de URL hace que el patrón de pestañas resulte incorrecto.

La propia pestaña suele implementarse con un <button>. La semántica del botón se combina de forma limpia con role="tab", y la gestión de foco y activación se obtiene de forma automática.

Contrato de teclado y foco

Según el patrón de pestañas APG:

  • Tab desplaza el foco al interior del tablist, situándolo sobre la pestaña activa. Un nuevo Tab mueve el foco FUERA, normalmente hacia el propio tabpanel si dispone de tabindex="0".
  • Las teclas de dirección Izquierda/Derecha (o Arriba/Abajo en tablists verticales) mueven el foco entre pestañas.
  • Inicio / Fin saltan a la primera / última pestaña.
  • La activación puede ser automática (el foco equivale a la selección) o manual (Espacio/Intro para seleccionar). Se recomienda el modo manual cuando activar una pestaña implica operaciones costosas.

Se debe usar un tabindex itinerante («roving tabindex»): solo la pestaña seleccionada tiene tabindex="0".

Errores habituales

  • Todas las pestañas con tabindex="0" — Tab recorre cada pestaña en lugar del panel.
  • Falta el enlace aria-controls que une la pestaña con el tabpanel.
  • aria-selected="true" en más de una pestaña simultáneamente.
  • Pestañas implementadas con <a href="#section"> — el fragmento de URL cambia, el botón atrás navega entre pestañas y el patrón se rompe.
  • Sin gestión de foco al activar: al hacer clic en una pestaña se actualiza el panel, pero el siguiente Tab retrocede hasta el encabezado de la página en lugar de entrar en el panel.

Ejemplo

<div role="tablist" aria-label="Account settings">
  <button role="tab" id="t-profile"  aria-selected="true"  aria-controls="p-profile"  tabindex="0">Profile</button>
  <button role="tab" id="t-billing"  aria-selected="false" aria-controls="p-billing"  tabindex="-1">Billing</button>
  <button role="tab" id="t-security" aria-selected="false" aria-controls="p-security" tabindex="-1">Security</button>
</div>
<section role="tabpanel" id="p-profile"  aria-labelledby="t-profile"  tabindex="0">…</section>
<section role="tabpanel" id="p-billing"  aria-labelledby="t-billing"  hidden>…</section>
<section role="tabpanel" id="p-security" aria-labelledby="t-security" hidden>…</section>