El orden de tabulación predeterminado que proporciona la posición del DOM de los elementos HTML semánticos 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 de forma explícita la posición de la pestaña de un elemento.
tabindex
se puede aplicar a cualquier elemento, aunque no es necesariamente útil en todos los elementos, y toma un rango de valores enteros. Con tabindex
, puedes especificar un orden explícito para los elementos de página que se pueden enfocar, insertar un elemento que, de otro modo, no se puede 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. Para enfocar el elemento, presiona Tab o llama a su método focus()
.
tabindex="-1"
: Quita un elemento del orden de tabulación natural, pero se puede enfocar el elemento llamando a su método focus()
.
tabindex="5"
: Cualquier valor de tabindex superior a 0
coloca ese elemento al principio del orden de tabulación natural. Si hay varios elementos con un valor de tabindex superior a 0
, el orden de tabulación comienza desde el valor más bajo que sea superior a cero y avanza hacia arriba.
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 para que la secuencia de DOM proporcione un orden de tabulación lógico. Si usas tabindex
, resérvalo para 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 ingresar información.
Agrega tabindex
solo al contenido que sea 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 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 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 de tabulación natural. Esta técnica, llamada administración del enfoque, mantiene el contexto percibido del usuario sincronizado 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 esté allí, puedes usar las teclas de flecha para exponer opciones adicionales que se pueden seleccionar.
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 del teclado implementar. En la guía de Prácticas de autoría de aplicaciones web enriquecidas 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 parecen a un conjunto de botones de selección, pero con tu 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 autor de ARIA. La sección 2 contiene una lista de patrones de diseño, incluida la tabla de características para grupos de radio, 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 índice de tabulación itinerante.
El índice de tabulación itinerante funciona estableciendo tabindex
en -1 para todos los elementos secundarios, excepto el 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 al primero, según la dirección en la que mueve el enfoque), el enfoque vuelve al primero (o al último).
Prueba el siguiente ejemplo. Inspecciona el elemento en DevTools para observar cómo el índice de tabulación se mueve de un botón de selección al siguiente.
Ventanas modales y trampas del 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 de 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.