Cómo controlar el enfoque con tabindex

Los elementos HTML estándar, como <button> o <input>, tienen accesibilidad para el teclado integrada y deben usarse siempre que sea posible. Sin embargo, si necesitas compilar elementos interactivos personalizados, puedes crear el comportamiento del usuario esperado si agregas tabindex.

Navegadores compatibles

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

Origen

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.

¿Qué es tabindex?

En caso de que necesites modificar el orden de tabulación predeterminado que proporcionan los elementos integrados, puedes usar el atributo HTML tabindex para establecer de forma explícita la posición de tabulación de un elemento.

tabindex se puede aplicar a cualquier elemento, aunque solo debe aplicarse a elementos interactivos, y puede aceptar un rango de 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í. El uso de un tabindex superior a 0 se considera un antipatrón.

Asegúrate de que se pueda acceder a los controles con el teclado

Una herramienta como Lighthouse es excelente para detectar automáticamente ciertos problemas de accesibilidad. Sin embargo, algunas pruebas aún deben realizarse de forma manual.

Intenta presionar la tecla Tab para navegar por tu sitio. ¿Puedes acceder a todos los controles interactivos de la página? De lo contrario, es posible que debas usar tabindex para mejorar la capacidad de enfoque de esos controles.

Administra el enfoque a nivel de la página

A veces, tabindex ayuda a crear una experiencia del usuario fluida. Por ejemplo, si compilas una página única sólida con diferentes secciones de contenido, en las que parte del contenido se oculta en diferentes puntos de la carga de la página. 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 elementos personalizados.

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.

Cómo insertar un elemento en el orden de tabulación

Inserta un elemento en el orden natural de pestañas con tabindex="0". Por ejemplo:

<div tabindex="0">Focus me with the TAB key</div>

Para enfocar un elemento, presiona la tecla Tab o llama al método focus() del elemento.

Cómo quitar un elemento del orden de tabulación

Quita un elemento con tabindex="-1". Por ejemplo:

<button tabindex="-1">Can't reach me with the TAB key!</button>

Esto quita un elemento del orden natural de pestañas, pero el elemento aún puede enfocarse mediante una llamada a su método focus().

Aplicar tabindex="-1" a un elemento no afecta a sus elementos secundarios. Si están en el orden de tabulación de forma natural o debido a un valor tabindex, permanecerán en el orden de tabulación. Para quitar un elemento y todos sus elementos secundarios del orden de tabulación, considera usar el polyfill inert de WICG. El polyfill emula el comportamiento de un atributo inert propuesto, que evita que las tecnologías de accesibilidad seleccionen o lean elementos.

Evita tabindex > 0

Cualquier tabindex superior a 0 hace saltar al elemento al principio del orden natural de pestañas. Si existen varios elementos con un tabindex superior a 0, el orden de pestañas comienza desde el valor más bajo que sea mayor que cero y va subiendo desde ahí.

El uso de un tabindex superior a 0 se considera un antipatrón porque los lectores de pantalla navegan por la página en orden DOM, no en orden de tabulación. Si necesitas que un elemento aparezca antes en el orden de tabulación, se debe mover a una posición anterior en el DOM.

Con Lighthouse, puedes identificar elementos con un tabindex > 0. Ejecuta la auditoría de accesibilidad (Lighthouse > Options > Accessibility) y busca los resultados de la auditoría "No hay ningún elemento con un valor de [tabindex] superior a 0".

Usar "tabindex itinerante"

Si estás compilando un componente complejo, es posible que debas agregar compatibilidad adicional con el teclado más allá del enfoque. Cuando sea posible, usa el elemento select integrado. Se puede enfocar y permite que las teclas de flecha expongan opciones adicionales que se pueden seleccionar.

Para implementar funciones similares en tus propios componentes, puedes usar una técnica conocida como "tabindex itinerante". El tabindex itinerante funciona configurando tabindex en -1 para todos los elementos secundarios, excepto el que está activo en el momento. Luego, el componente usa un objeto de escucha de eventos de teclado para determinar qué tecla presionó el usuario.

Cuando esto sucede, el componente 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 focus() en él.

Antes

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="0">Redo</button>
  <button tabindex="-1">Cut</button>
</div>

Después

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="-1">Redo</button>
  <button tabindex="0">Cut</button>
</div>

Recetas de acceso con el teclado

Si no sabes qué nivel de compatibilidad con el teclado podrían necesitar tus componentes personalizados, puedes consultar las Prácticas de redacción de ARIA 1.1. En esta guía, se enumeran los patrones comunes de la IU y se identifican las teclas que deben admitir tus componentes.