Navegación por Teclado: Haciendo Tu Sitio Web Usable Sin Ratón
Introducción
La navegación por teclado es la capacidad de usar un sitio web solo con el teclado—sin ratón, touchpad o pantalla táctil requeridos. Esto no es solo conveniencia; es un requisito fundamental de accesibilidad. WCAG 2.1.1 exige que toda la funcionalidad debe estar disponible desde un teclado, haciendo este uno de los criterios de accesibilidad más críticos.
Millones de usuarios dependen de la navegación por teclado: personas con discapacidades motoras que no pueden usar un ratón, usuarios ciegos que navegan con lectores de pantalla, usuarios avanzados que prefieren atajos de teclado, y cualquiera con una lesión temporal que afecte el uso del ratón.
Quién Necesita Navegación por Teclado
Usuarios Principales
- Usuarios con discapacidades motoras - Pueden usar dispositivos de entrada alternativos que emulan teclados
- Usuarios ciegos - Los lectores de pantalla dependen de la navegación por teclado
- Usuarios con baja visión - A menudo combinan teclado con magnificación de pantalla
- Lesión por esfuerzo repetitivo - El teclado puede ser menos doloroso que el ratón
- Usuarios avanzados - Prefieren atajos de teclado por eficiencia
Dispositivos de Entrada Alternativos Comunes
| Dispositivo |
Función |
Emula |
| Dispositivo de conmutación |
Uno o múltiples interruptores para entrada |
Teclas de teclado |
| Sip-and-puff |
Entrada controlada por respiración |
Teclado/ratón |
| Seguimiento ocular |
Selección basada en mirada |
Ratón/teclado |
| Control por voz |
Comandos de voz |
Teclado/ratón |
| Puntero de cabeza |
Seguimiento del movimiento de la cabeza |
Ratón |
Todos estos dispositivos finalmente funcionan a través de interacción de teclado, haciendo la accesibilidad de teclado la base para soporte de dispositivos más amplio.
Operaciones Esenciales de Teclado
Teclas de Navegación Estándar
| Tecla |
Función |
| Tab |
Mover al siguiente elemento enfocable |
| Shift + Tab |
Mover al elemento enfocable anterior |
| Enter |
Activar enlaces y botones |
| Espacio |
Activar botones, alternar checkboxes |
| Teclas de flecha |
Navegar dentro de componentes (menús, tabs, grillas) |
| Escape |
Cerrar diálogos, cancelar operaciones |
| Home/End |
Saltar al primer/último elemento en listas |
Requisitos de Teclado WCAG
| Criterio |
Nivel |
Requisito |
| 2.1.1 Teclado |
A |
Toda funcionalidad accesible vía teclado |
| 2.1.2 Sin Trampa de Teclado |
A |
El foco siempre puede moverse fuera de cualquier elemento |
| 2.1.4 Atajos de Tecla de Carácter |
A |
Los atajos de una sola tecla pueden desactivarse/remapearse |
| 2.4.3 Orden del Foco |
A |
La secuencia de foco debe ser lógica |
Problemas Comunes de Accesibilidad de Teclado
1. Elementos Interactivos No Enfocables
<div onclick="submitForm()">Enviar</div>
<button type="submit">Enviar</button>
<div role="button" tabindex="0" onclick="submitForm()" onkeydown="handleKey(event)">
Enviar
</div>
2. Trampas de Teclado
modal.addEventListener('keydown', (e) => {
e.preventDefault();
});
modal.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeModal();
if (e.key === 'Tab') handleFocusTrap(e);
});
3. Skip Links Faltantes
<nav>
</nav>
<main>Contenido aquí</main>
<a href="#main-content" class="skip-link">Saltar al contenido principal</a>
<nav>
</nav>
<main id="main-content">Contenido aquí</main>
4. Orden de Foco Ilógico
<div style="display: flex; flex-direction: row-reverse;">
<button>Tercero visualmente, primero en DOM</button>
<button>Segundo visualmente y en DOM</button>
<button>Primero visualmente, tercero en DOM</button>
</div>
5. Interacciones Solo por Hover
.dropdown-menu {
display: none;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.dropdown:hover .dropdown-menu,
.dropdown:focus-within .dropdown-menu {
display: block;
}
Probando Navegación por Teclado
Prueba Manual Rápida
- Desconecta tu ratón o déjalo a un lado
- Presiona Tab - ¿El foco se mueve a través de todos los elementos interactivos?
- Verifica visibilidad del foco - ¿Puedes ver dónde estás?
- Prueba activación - ¿Enter y Espacio funcionan correctamente?
- Busca trampas - ¿Siempre puedes navegar con Tab fuera de cualquier elemento?
- Verifica modales - ¿Puedes cerrarlos con Escape?
Qué Verificar en Cada Página
- [ ] Todos los enlaces pueden alcanzarse y activarse
- [ ] Todos los botones pueden alcanzarse y activarse
- [ ] Todos los campos de formulario pueden llenarse y enviarse
- [ ] Todos los menús/dropdowns pueden abrirse y navegarse
- [ ] Todos los modales pueden abrirse y cerrarse
- [ ] El orden del foco coincide con el orden visual/de lectura
- [ ] No existen trampas de teclado
- [ ] Los skip links están disponibles
Áreas Problemáticas Comunes
- Dropdowns personalizados - A menudo les falta soporte de teclado
- Carruseles/sliders - Pueden atrapar el foco o saltar controles
- Diálogos modales - Necesitan trampa de foco y Escape para cerrar
- Mega menús - Patrones de navegación complejos
- Reproductores de video - Los controles personalizados a menudo son inaccesibles
- Elementos canvas - Necesitan alternativas de teclado
Elementos Nativos vs Personalizados
Usar Elementos Nativos Cuando Sea Posible
| Elemento Nativo |
Alternativa Personalizada |
Teclado Incorporado |
<button> |
<div role="button"> |
✅ Nativo lo tiene |
<a href> |
<span onclick> |
✅ Nativo lo tiene |
<select> |
Dropdown personalizado |
✅ Nativo lo tiene |
<input type="checkbox"> |
Toggle personalizado |
✅ Nativo lo tiene |
<details> |
Acordeón personalizado |
✅ Nativo lo tiene |
Cuando Se Necesitan Componentes Personalizados
Si debes usar componentes personalizados, implementa:
- tabindex=“0” - Hace el elemento enfocable
- Role - Indica a los lectores de pantalla qué es
- Manejadores de teclado - Enter, Espacio, teclas de flecha según corresponda
- Gestión de foco - Mover el foco cuando sea necesario
Correcciones Rápidas
Haciendo un Div Clickeable y Accesible por Teclado
<div onclick="doAction()">Haz click</div>
<div
role="button"
tabindex="0"
onclick="doAction()"
onkeydown="if(event.key==='Enter'||event.key===' ')doAction()"
>
Haz click
</div>
<button onclick="doAction()">Haz click</button>
Agregando un Skip Link
<a href="#main" class="skip-link">Saltar al contenido principal</a>
<style>
.skip-link {
position: absolute;
top: -40px;
left: 0;
padding: 8px;
background: #000;
color: #fff;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
</style>
Resumen de Mejores Prácticas
| Hacer |
No Hacer |
| Usar elementos HTML nativos |
Construir controles personalizados innecesariamente |
| Probar sin ratón |
Asumir que probar con ratón cubre teclado |
| Proporcionar skip links |
Forzar a usuarios a través de toda la navegación |
| Hacer el foco visible |
Eliminar indicadores de foco |
| Usar orden de tab lógico |
Usar valores de tabindex positivos |
| Soportar Enter y Espacio |
Requerir hover para funcionalidad |
Artículos Relacionados
Referencias
- W3C - WCAG 2.2 SC 2.1.1 Keyboard
- W3C - WCAG 2.2 SC 2.1.2 No Keyboard Trap
- WebAIM - Keyboard Accessibility
- MDN - Keyboard-navigable JavaScript widgets