El orden de tabulación predeterminado que proporciona la posición en el DOM de los elementos HTML semánticos es conveniente, pero es posible que, en ocasiones, debas modificarlo. Mover elementos en el HTML es ideal, pero podría no ser factible. En estos casos, puedes usar el atributo HTML tabindex
para establecer de forma explícita la posición de la pestaña de un elemento.
tabindex
se puede aplicar a cualquier elemento, aunque no necesariamente es útil en todos los elementos, y toma un rango de valores enteros. Con tabindex
, puedes especificar un orden explícito para los elementos de la página enfocables, insertar un elemento que, de otro modo, no se podría enfocar en el orden de tabulación y quitar elementos del orden de tabulación. Por ejemplo:
tabindex="0"
: Inserta un elemento en el orden de tabulación natural. Se puede enfocar el elemento presionando Tab o llamando a su método focus()
.
tabindex="-1"
: Quita un elemento del orden de tabulación natural, pero el elemento aún se puede enfocar llamando a su método focus()
.
tabindex="5"
: Cualquier tabindex mayor que 0
lleva ese elemento al frente del orden de tabulación natural. Si hay varios elementos con un tabindex mayor que 0
, el orden de tabulación comienza con el valor más bajo que sea mayor que cero y aumenta progresivamente.
Esto es especialmente cierto para los elementos que no son de entrada, como los encabezados, las imágenes o los títulos de los artículos. Cuando sea posible, es mejor organizar el código fuente de modo que la secuencia del DOM proporcione un orden de tabulación lógico. Si usas tabindex
, restringe su uso 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 esperar proporcionar entrada.
Solo agrega tabindex
al contenido interactivo. Incluso si el contenido es importante, como una imagen clave, los usuarios de lectores de pantalla pueden comprenderlo sin necesidad de agregar enfoque.
Administra el enfoque a nivel de la página
A veces, tabindex
es necesario para una experiencia del usuario fluida. Por ejemplo, si compilas una página única sólida con diferentes secciones de contenido, en la que no todo el contenido es visible de forma simultánea. Esto podría significar que los vínculos de navegación cambian el contenido visible sin que se actualice 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 de tabulación natural. Esta técnica, llamada administración del enfoque, mantiene el contexto percibido por el usuario sincronizado con el contenido visual del sitio.
Administra 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 allí, puedes usar las teclas de flecha para exponer opciones seleccionables adicionales.
Si compilas un elemento select
personalizado, es importante replicar ese comportamiento para que los usuarios del teclado puedan seguir interactuando con tu control.
Puede ser difícil saber qué comportamientos del teclado implementar. En la guía de Prácticas de creación de aplicaciones de Internet enriquecidas y accesibles (ARIA), se enumeran los tipos de componentes y los tipos de acciones del teclado que admiten.
Quizás estés trabajando en elementos personalizados que se asemejan a un conjunto de botones de selección, pero con tu propia versión única de 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 de creación de ARIA. La sección 2 contiene una lista de patrones de diseño, incluida una tabla de características para los grupos de botones de opción, el componente existente que coincide más con tu elemento nuevo.
Uno de los comportamientos comunes del teclado que se deben admitir son las teclas de flecha hacia arriba, abajo, izquierda y derecha. Para agregar este comportamiento al nuevo componente, usamos una técnica llamada tabindex itinerante.
El índice de tabulación itinerante funciona estableciendo tabindex
en -1 para todos los elementos secundarios, excepto el que está activo actualmente.
<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 enfocado anteriormente en -1, establece el tabindex
del elemento secundario que se enfocará en 0 y llama al método de enfoque en él.
<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 (o primer, según la dirección en la que mueva el enfoque) elemento secundario, el enfoque vuelve al primer (o último) elemento secundario.
Prueba el siguiente ejemplo. Inspecciona el elemento en las Herramientas para desarrolladores para observar cómo el tabindex se mueve de un botón de selección al siguiente.
Ventanas modales y trampas de teclado
Es mejor evitar la administración manual del enfoque, ya que puede generar situaciones complicadas. Por ejemplo, un widget de autocompletar que intenta administrar el enfoque y captura el comportamiento de la pestaña, pero impide que el usuario salga de él hasta que se complete. Esto se denomina trampa de teclado y puede ser muy frustrante para el usuario.
La sección 2.1.2 de las WCAG indica que el enfoque del teclado nunca debe bloquearse ni quedar atrapado en un elemento de página en particular. El usuario debe poder navegar hacia todos los elementos de la página y desde ellos solo con el teclado.
La excepción a esta regla son los modales. Sin embargo, debes evitar usar tabindex
cuando crees un diálogo modal. Con inert
, puedes asegurarte de que los usuarios no interactúen accidentalmente con un elemento (una trampa de teclado intencional). Usa el elemento <dialog>
, que es inerte de forma predeterminada, para crear un diálogo modal para los usuarios y bloquear los clics y las pestañas fuera del diálogo modal. Esto permite que el usuario se concentre en una selección obligatoria.