Cómo usar tabindex

Dave Gash
Dave Gash
Meggin Kearney
Meggin Kearney

El orden de tabulación predeterminado que determina la posición de los elementos HTML semánticos en el DOM es conveniente, pero es posible que en ocasiones debas modificarlo. Mover elementos en el código HTML es lo ideal, pero es posible que no sea factible. En estos casos, puedes usar el atributo HTML tabindex para establecer explícitamente la posición de pestaña de un elemento.

Navegadores compatibles

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Origen

tabindex se puede aplicar a cualquier elemento, aunque no necesariamente resulta útil para todos los elementos, y puede llevar varios valores enteros. Con tabindex, puedes especificar un orden explícito para los elementos de página que pueden tener el foco, insertar un elemento que de otra manera no podría tener el foco en el orden de tabulación y quitar elementos del orden de pestañas. Por ejemplo:

tabindex="0": Inserta un elemento en el orden natural de pestañas. Para enfocar el elemento, presiona Tab, y para enfocarlo, llama a su método focus().

tabindex="-1": Quita un elemento del orden natural de pestañas, pero el elemento todavía puede tomar el foco mediante una llamada a su método focus().

tabindex="5": Cualquier tabindex superior a 0 lleva ese elemento al principio del orden natural de pestañas. Si existen varios elementos con un tabindex superior a 0, el orden de tabulación comienza desde el valor más bajo que sea mayor que cero y va subiendo desde ahí.

Esto es así especialmente para los elementos que no son de entrada, como encabezados, imágenes o títulos de artículos. Cuando sea posible, es mejor ordenar tu código fuente para que la secuencia DOM aporte un orden de tabulación lógico. Si usas tabindex, limítalo a controles interactivos personalizados, como botones, pestañas, menús desplegables y campos de texto; es decir, elementos en los que el usuario podría pretender realizar entradas.

Agrega tabindex solo al contenido interactivo. Incluso si el contenido es importante, como una imagen clave, los usuarios de lectores de pantalla pueden comprenderlo sin agregar enfoque.

Administra el enfoque a nivel de la página

A veces, tabindex es necesario para que la experiencia del usuario sea fluida. Por ejemplo, si compilas una página única sólida con diferentes secciones de contenido, en las que no todo el contenido es visible al mismo tiempo. Esto podría significar que los vínculos de navegación cambian el contenido visible sin actualizar la página.

En este caso, identifica el área de contenido seleccionada, asígnale un tabindex de -1 y llama a su método focus. Esto garantiza que el contenido no aparezca en el orden natural de pestañas. Esta técnica, llamada administración de foco, mantiene el contexto percibido del usuario en sincronización con el contenido visual del sitio.

Cómo administrar el enfoque en los componentes

En algunos casos, también debes administrar el enfoque a nivel del control, como con los componentes personalizados.

Por ejemplo, el elemento select puede recibir el enfoque básico, pero una vez que lo hace, puedes usar las teclas de dirección para exponer opciones seleccionables adicionales. Si compilas un elemento select personalizado, es importante replicar ese comportamiento para que los usuarios del teclado puedan interactuar con tu control.

Puede ser difícil saber qué comportamientos de teclado implementar. En la guía de prácticas para autores de apps de Internet enriquecidas accesibles (ARIA), se enumeran los tipos de componentes y qué tipos de acciones de teclado admiten.

Tal vez estés trabajando en elementos personalizados que se parecen a un conjunto de botones de selección, pero con tu toque personal en su apariencia y comportamiento.

<radio-group>
    <radio-button>Water</radio-button>
    <radio-button>Coffee</radio-button>
    <radio-button>Tea</radio-button>
    <radio-button>Cola</radio-button>
    <radio-button>Ginger Ale</radio-button>
</radio-group>

Para determinar qué compatibilidad con el teclado necesitan, consulta la guía de prácticas para autores de ARIA. La sección 2 contiene una lista de patrones de diseño, incluida la tabla de características para grupos de selección, que es el componente existente que más se asemeja a tu elemento nuevo.

Uno de los comportamientos comunes de teclado que debería admitirse es el de las teclas de flecha hacia arriba/abajo/izquierda/derecha. Para agregar este comportamiento al nuevo componente, usamos una técnica llamada tabindex itinerante.

El tabindex itinerante funciona configurando tabindex en -1 para todos los elementos secundarios excepto el que se encuentra activo en el momento.

<radio-group>
  <radio-button tabindex="0">Water</radio-button>
  <radio-button tabindex="-1">Coffee</radio-button>
  <radio-button tabindex="-1">Tea</radio-button>
  <radio-button tabindex="-1">Cola</radio-button>
  <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

El componente usa un objeto de escucha de eventos de teclado para determinar qué tecla presiona el usuario. Cuando esto sucede, establece el tabindex del elemento secundario que tenía previamente el foco en -1, establece el tabindex del elemento secundario que va a recibir el foco en 0 y llama al método de enfoque para el mismo.

<radio-group>
    <!-- Assuming the user pressed the down arrow, we'll focus the next available child -->
    <radio-button tabindex="-1">Water</radio-button>
    <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element
    <radio-button tabindex="-1">Tea</radio-button>
    <radio-button tabindex="-1">Cola</radio-button>
    <radio-button tabindex="-1">Ginger Ale</radio-button>
</radio-group>

Cuando el usuario llega al último elemento secundario (o al primero, según la dirección en la que mueve el enfoque), el enfoque vuelve al primer elemento secundario (o al último).

Prueba el siguiente ejemplo. Inspecciona el elemento en DevTools para observar el desplazamiento del tabindex de un botón de selección al siguiente.

Ventanas modales y trampas de teclado

Es mejor evitar administrar el enfoque de forma manual, ya que puede generar situaciones complicadas. Por ejemplo, un widget de autocompletado que intenta administrar el enfoque y capturar el comportamiento de la pestaña, pero evita que el usuario lo deje hasta que se complete. Esto se denomina trampa del teclado y puede ser muy frustrante para el usuario.

El artículo 2.1.2 del WCAG establece que el enfoque del teclado nunca debe bloquearse ni atraparse en un elemento de página en particular. El usuario debe poder navegar a todos los elementos de la página y desde ellos solo con el teclado.

La excepción a esta regla son los elementos modales. Sin embargo, aún así debes evitar usar tabindex cuando crees un elemento modal. Con inert, puedes asegurarte de que los usuarios no puedan interactuar accidentalmente con un elemento (una trampa de teclado intencional). Usa el elemento <dialog>, que es inerte de forma predeterminada, para crear un elemento modal para los usuarios y, al mismo tiempo, bloquear los clics y las pestañas fuera de él. Esto permite que el usuario se enfoque en una selección obligatoria.