Curso HTML 11.4 Navegación por teclado y orden de tabulación (tabindex)

Navegación por teclado y orden de tabulación (tabindex)

La navegación por teclado en HTML permite a los usuarios recorrer elementos interactivos (enlaces, botones, formularios…) utilizando la tecla Tab (o combinaciones asociadas). El atributo tabindex define cómo y en qué orden los elementos reciben el foco. A continuación veremos en detalle los mecanismos nativos y cómo personalizar el comportamiento.

1. Comportamiento nativo sin tabindex

  • El orden de tabulación sigue el flujo del documento (orden de aparición en el DOM).
  • Sólo son foco-nables de forma predeterminada:
    • Enlaces (<a href='...'>).
    • Botones (<button>, <input type='button'>…).
    • Campos de formulario (<input>, <textarea>, <select>…).
    • Áreas de imagen (<area> con href).

<a href='#seccion1'>Ir a sección 1</a> <button>Enviar</button> <a href='#seccion2'>Ir a sección 2</a> <input type='text' placeholder='Nombre'> </div>

2. Atributo tabindex y sus valores

tabindex acepta valores enteros (pueden interpretarse positivos, cero o negativos), cada uno con efectos distintos:

Valor Comportamiento
<0 El elemento es foco-nabe programáticamente (elem.focus()) pero no forma parte de la secuencia tabulable.
0 El elemento entra en el orden de tabulación en su posición natural, junto a los elementos predeterminados.
>0 Se crea un orden explícito: primero los más bajos, de manera ascendente; tras ellos, el resto con tabindex='0' y elementos nativos.

2.1 tabindex='-1'

Permite que un elemento reciba foco con element.focus() (útil para gestionar diálogos modales, mensajes de error…), pero no con la tecla Tab.

<div tabindex='-1' id='mensaje-error'>
  


Error: falta información.

</div> <script> // Al producirse el error, centramos foco en el div: document.getElementById('mensaje-error').focus(); </script>

2.2 tabindex='0'

Hace foco-nables elementos que no lo son por defecto (por ejemplo, <div>, <span>) y los integra en el flujo natural de tabulación.

<div tabindex='0'>Este div puede recibir foco con Tab</div>
<span tabindex='0'>Este span también es foco-nabe</span>

2.3 tabindex positivo

Define un orden manual. Sólo debería usarse en contenedores muy concretos, pues:

  1. Agregar o quitar elementos obliga a recalcular valores.
  2. Puede resultar confuso para dispositivos de asistencia.
<button tabindex='2'>Paso 2</button>
<button tabindex='1'>Paso 1</button>
<button tabindex='3'>Paso 3</button>

3. Buenas prácticas con tabindex

  • Evitar tabindex>0 salvo en casos muy específicos (por ejemplo, menús con navegación compleja).
  • Usar tabindex='0' para componentes interactivos creados con elementos genéricos (<div> o <span>).
  • Emplear tabindex='-1' para gestionar foco programático (diálogos, menús desplegables, retorno de foco).
  • No mezclar valores tabindex positivos en grandes páginas; mejor reorganizar el DOM o usar JavaScript para controlar foco.
  • Probar siempre con lector de pantalla y sólo teclas (Tab, Shift+Tab, Enter, Espacio, flechas).

4. Ejemplo avanzado: menú con “roving tabindex”

El Roving Tabindex es una técnica para menús de pestañas o ítems seleccionables: mantenemos un solo tabindex='0' y movemos ese foco al elemento activo.

<ul role='tablist'>
  <li role='presentation'>
    <button role='tab' tabindex='0' aria-selected='true'>Pestaña 1</button>
  </li>
  <li role='presentation'>
    <button role='tab' tabindex='-1'>Pestaña 2</button>
  </li>
  <li role='presentation'>
    <button role='tab' tabindex='-1'>Pestaña 3</button>
  </li>
</ul>

<script>
  const tabs = document.querySelectorAll('[role='tab']');
  let current = 0;

  tabs.forEach((tab, index) => {
    tab.addEventListener('keydown', e => {
      if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
        tabs[current].setAttribute('tabindex', '-1');
        tabs[current].setAttribute('aria-selected', 'false');

        if (e.key === 'ArrowRight') {
          current = (current + 1) % tabs.length;
        } else {
          current = (current - 1 + tabs.length) % tabs.length;
        }

        tabs[current].setAttribute('tabindex', '0');
        tabs[current].setAttribute('aria-selected', 'true');
        tabs[current].focus();
        e.preventDefault();
      }
    });
  });
</script>

5. Resumen

  • Atender al orden natural del DOM y usar tabindex='0' para solo mejorar accesibilidad puntual.
  • Evitar tabindex>0 en la mayoría de casos.
  • Usar tabindex='-1' para control de foco programático y componentes emergentes.
  • Probar siempre con teclado y tecnologías de asistencia.

Con estas pautas y ejemplos podrás dominar el orden de tabulación y la navegación por teclado, garantizando una experiencia accesible y coherente para todos los usuarios.


Publicado

en

por

Etiquetas:

Comentarios

Deja una respuesta