Skip to content
Aprender Medir Blog Case studies About
En esta página
  • Comprueba si tus controles son accesibles desde el teclado
  • Inserta un elemento en el orden de pestañas
  • Elimina un elemento del orden de pestañas
  • Evita tabindex > 0
  • Crea componentes accesibles con "roving tabindex" o "tabindex itinerante"
  • Fórmulas de acceso al teclado

Controlar el enfoque con tabindex

Nov 18, 2018
Available in: 한국어, Português, Русский, 中文, English
Appears in: Accesible para todos
Rob Dodson
Rob Dodson
TwitterGitHubGlitchHomepage
En esta página
  • Comprueba si tus controles son accesibles desde el teclado
  • Inserta un elemento en el orden de pestañas
  • Elimina un elemento del orden de pestañas
  • Evita tabindex > 0
  • Crea componentes accesibles con "roving tabindex" o "tabindex itinerante"
  • Fórmulas de acceso al teclado

Los elementos HTML estándar como <button> o <input> participan en la navegación secuencial del teclado de forma accesible. Sin embargo, si estás creando componentes interactivos personalizados utilizatabindex para asegurarte de que sean accesibles desde el teclado.

Siempre que sea posible, utiliza un elemento HTML integrado en lugar de crear su propia versión personalizada. <button>, por ejemplo, es muy fácil de diseñar y ya tiene compatibilidad total con el teclado. Esto te evitará tener que administrar tabindex o agregar semántica con ARIA.

Comprueba si tus controles son accesibles desde el teclado #

Una herramienta como Lighthouse es excelente para detectar ciertos problemas de accesibilidad, pero algunas cosas solo pueden ser probadas por humanos.

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

Advertencia

Si no ves ningún indicador de enfoque, es posible que tu CSS lo oculte. Comprueba si hay estilos que mencionen :focus { outline: none; }. Puedes aprender cómo solucionar este problema en nuestra guía sobre enfoque de estilo.

Inserta un elemento en el orden de pestañas #

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

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

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

Elimina un elemento del orden de pestañas #

Elimina un elemento usando tabindex="-1". Por ejemplo:

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

Esto elimina un elemento del orden natural de pestañas, pero el elemento aún se puede enfocar llamando a su método focus().

Tené en cuenta que aplicar tabindex="-1" a un elemento no afecta a sus elementos secundarios; si están en el orden de pestañas de forma natural o debido a un tabindex de tabulación, permanecerán en el orden de pestañas. Para eliminar un elemento y todos sus elementos secundarios del orden de tabulación, considera usar el polyfill WICG inert. El polyfill emula el comportamiento del atributo propuesto inert, que evita que los elementos sean seleccionados o leídos por tecnologías de asistencia.

Precaución

El polyfill inert es experimental y es posible que no funcione como se esperaba en todos los casos. Prueba cuidadosamente antes de usarlo en producción.

Evita tabindex > 0 #

Cualquier tabindex mayor que 0 salta el 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 desde el valor más bajo mayor que cero y avanza hacia arriba.

El uso de un tabindex mayor que 0 se considera un anti-patró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, debe moverse a un lugar anterior en el DOM.

Lighthouse facilita la identificación de elementos con un tabindex > 0. Ejecuta la Auditoría de accesibilidad (Lighthouse> Opciones> Accesibilidad) y busque los resultados de la auditoría "Ningún elemento tiene un valor [tabindex] mayor que 0".

Crea componentes accesibles con "roving tabindex" o "tabindex itinerante" #

Si estás construyendo un componente complejo, es posible que necesites añadir soporte adicional para el teclado más allá del enfoque. Considera el elemento select incorporado. Es enfocable y puede usar las teclas de flecha para exponer funcionalidades adicionales (las opciones seleccionables).

Para implementar una funcionalidad similar en sus propios componentes, utiliza una técnica conocida como " tabindex itinerante". El tabindex itinerante o roving tabindex funciona estableciendo tabindex en -1 para todos los elementos secundarios, excepto el que está actualmente activo. A continuación, el componente utiliza un detector de eventos de teclado para determinar qué tecla ha pulsado el usuario.

Cuando esto sucede, el componente establece el tabindex de tabulación del elemento secundario previamente enfocado en -1, establece el tabindex de tabulación del elemento secundario que se va a enfocar en 0 y llama al método focus() en él.

Antes

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

Después

<div role="toolbar">
<button tabindex="-1">Undo</div>
<button tabindex="-1">Redo</div>
<button tabindex="0">Cut</div>
</div>
¿Tienes curiosidad por saber para qué sirven esos atributos role=""? Te permiten cambiar la semántica de un elemento para que un lector de pantalla lo anuncie correctamente. Puedes obtener más información sobre ellos en nuestra guía sobre conceptos básicos de lectores de pantalla.
Test your knowledge of tab order

This HTML renders a modal dialog:

<div role="dialog" aria-labelledby="dialog-header">
<button aria-label="Close"></button>
<h2 id="dialog-header">
Do you want to allow notifications from this website?
</h2>
<button>No</button>
<button>Yes</button>
</div>

What is the tab order for the elements in the sample?

  1. The Close button
  2. The No button
  3. The Yes button

Only the <button> elements are included in the tab order because they're the only standardized HTML form elements. To insert other elements into the tab order, you would add a tabindex attribute.

<section tabindex="-1">
<h2>Cat facts</h2>
<ul>
<li>A group of cats is called a <a href="https://m-w.com/dictionary/clowder">clowder</a>.</li>
<li>Most cats are <a href="https://www.catfacts.org/catnip.html"> unaffected by catnip</a>.</li>
</ul>
</section>

Which elements from the sample are included in the tab order?

Only the <a> elements are included in the tab order.

The <section> element is not in the tab order because it has a negative tabindex value. (It can, however, be focused using the focus() method.) The tabindex value for the <section> element doesn't affect its children.

This HTML renders a popup menu followed by a search input:

<div role="menu" tabindex="0">
<a role="menuitem" href="/learn/" tabindex="-1">Learn</a>
<a role="menuitem" href="/measure/" tabindex="-1">Measure</a>
<a role="menuitem" href="/blog/" tabindex="-1">Blog</a>
<a role="menuitem" href="/about/" tabindex="-1">About</a>
</div>
<input tabindex="1" type="text" role="search" aria-label="Search" placeholder="Search">

Which element in the sample comes first in the tab order?

The Search text input comes first in the tab order. Because it has a tabindex greater than zero, it jumps to the front of the tab order.

(This behavior is likely to cause confusion if the menu is positioned on the page before the search input. This is an example of why having a tabindex value greater than zero is considered an anti-pattern.)

This HTML renders a custom radio group, which should have a roving tabindex. (To keep things simpler, ignore the aria-* attributes for now.)

<div role="radiogroup" aria-labelledby="breed-header">
<h3 id="breed-header">Your cat's breed</h3>
<div role="radio" aria-checked="false" tabindex="0">Persian</div>
<div role="radio" aria-checked="false" tabindex="-1">Bengal</div>
<div role="radio" aria-checked="false" tabindex="-1">Maine Coon</div>
</div>

When a role="radio" element is focused, what should happen when a user presses the Right arrow key?

  • Change the tabindex values for all radio elements in the group to -1.
  • If there's a radio element after the one that's focused, set its tabindex value to 0.
  • If there's no radio element after the one that's focused, set the tabindex value of the first radio element in the group to 0.
  • Focus the radio element that now has a tabindex of 0.

That's a lot—and it doesn't even include ARIA attributes! This is an example of why it's easier to use built-in elements with built-in keyboard behavior whenever you can.

Fórmulas de acceso al teclado #

Si no estás seguro de qué nivel de soporte de teclado pueden necesitar tus componentes personalizados, puedes consultar las Prácticas de creación de ARIA 1.1. Esta sencilla guía enumera los patrones de IU comunes e identifica qué claves deben admitir sus componentes.

Última actualización: Nov 18, 2018 — Mejorar el artículo
Return to all articles
Compartir
suscribir

Contribute

  • Presentar un error
  • Ver fuente

Contenido relevante

  • developer.chrome.com
  • Chrome Actualizaciones
  • Web Fundamentals
  • Case studies
  • Podcasts
  • Shows

Conectar

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • Todos los productos
  • Condiciones y privacidad
  • Principios de la Comunidad

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.