La accesibilidad web es clave para garantizar que todas las personas, incluidas aquellas que navegan con teclado o tecnologías de asistencia, puedan interactuar correctamente con los contenidos.
Un error frecuente es abrir un cuadro de diálogo o un menú sin ajustar el foco del teclado, lo que provoca que los usuarios tengan que recorrer toda la página para alcanzarlo. Esto incumple el Criterio de Conformidad 2.4.3 de WCAG 2.1 (Orden de foco), dificultando la navegación y el uso eficiente del contenido.
En este artículo, exploraremos el Fallo F85, cómo impacta en la accesibilidad y cómo solucionarlo con buenas prácticas.
Acerca de este fallo
El Fallo F85 ocurre cuando un cuadro de diálogo o menú se abre en un punto distinto del orden lógico de navegación y el foco no se mueve automáticamente hacia él.
El Criterio 2.4.3 de WCAG 2.1 establece que el orden de navegación debe preservar el significado y la operabilidad de los elementos. Si el foco no se mueve correctamente, los usuarios pueden perder el contexto y enfrentar barreras para completar tareas en la web.
Este fallo se manifiesta comúnmente cuando:
- Un menú o cuadro de diálogo se inserta al final del DOM sin ajustar el foco.
- Un usuario debe recorrer toda la página con Tab antes de acceder al menú o cuadro de diálogo.
- Al cerrar un cuadro de diálogo, el foco se pierde en la página en lugar de regresar al botón que lo activó.
Impacto en la accesibilidad:
- Usuarios de teclado pueden tardar demasiado en llegar al contenido relevante.
- Personas con discapacidad visual pierden el contexto si el foco no se mueve automáticamente.
- Usuarios con movilidad reducida enfrentan dificultad para navegar por elementos no alineados con el orden lógico.
Ejemplos
Ejemplo incorrecto 1: Cuadro de diálogo insertado al final del DOM
En este caso, un cuadro de diálogo se inserta al final del código HTML, sin mover el foco automáticamente.
Código incorrecto:
<button id=»openDialog»>Abrir diálogo</button>
<!– Diálogo al final del DOM –>
<div id=»dialog» style=»display: none;»>
<p>Este es un cuadro de diálogo</p>
<button id=»closeDialog»>Cerrar</button>
</div>
<script>
document.getElementById(«openDialog»).addEventListener(«click», function() {
document.getElementById(«dialog»).style.display = «block»;
});
</script>
🔴 Problema: El diálogo aparece visualmente, pero el foco permanece en el botón de activación. El usuario debe tabular por toda la página para alcanzarlo.
Solución correcta: Mover el foco al cuadro de diálogo
El foco debe moverse al diálogo cuando se abre y volver al botón original al cerrarse.
<button id=»openDialog»>Abrir diálogo</button>
<!– Diálogo cerca del botón de activación –>
<div id=»dialog» style=»display: none;» tabindex=»-1″>
<p>Este es un cuadro de diálogo</p>
<button id=»closeDialog»>Cerrar</button>
</div>
<script>
document.getElementById(«openDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «block»;
dialog.focus(); // Mueve el foco al cuadro de diálogo
});
document.getElementById(«closeDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «none»;
document.getElementById(«openDialog»).focus(); // Devuelve el foco al botón original
});
</script>
✅ ¿Qué mejora?: Ahora el usuario puede interactuar con el diálogo inmediatamente sin perder tiempo tabulando.
Ejemplo incorrecto 2: El foco vuelve al primer elemento en la página tras cerrar el cuadro de diálogo
En este caso, el usuario abre un cuadro de diálogo, pero al cerrarlo, el foco se traslada al primer elemento de la página en lugar del botón que lo activó.
<button id=»openDialog»>Abrir diálogo</button>
<div id=»dialog» style=»display: none;» tabindex=»-1″>
<p>Mensaje importante</p>
<button id=»closeDialog»>Cerrar</button>
</div>
<script>
document.getElementById(«openDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «block»;
dialog.focus();
});
document.getElementById(«closeDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «none»;
document.body.focus(); // Foco vuelve al primer elemento de la página
});
</script>
🔴 Problema: El usuario debe navegar desde el inicio de la página para volver al punto donde estaba antes de abrir el cuadro de diálogo.
Solución correcta: Restaurar el foco en el botón original
El foco debe regresar al botón de activación para evitar que el usuario pierda la referencia en la página.
<button id=»openDialog»>Abrir diálogo</button>
<div id=»dialog» style=»display: none;» tabindex=»-1″>
<p>Mensaje importante</p>
<button id=»closeDialog»>Cerrar</button>
</div>
<script>
let lastFocusedElement;
document.getElementById(«openDialog»).addEventListener(«click», function(event) {
lastFocusedElement = event.target;
let dialog = document.getElementById(«dialog»);
dialog.style.display = «block»;
dialog.focus();
});
document.getElementById(«closeDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «none»;
lastFocusedElement.focus(); // Devuelve el foco al botón que activó el diálogo
});
</script>
✅ ¿Qué mejora?: Ahora, al cerrar el diálogo, el usuario recupera su ubicación original.
Ejemplo correcto: Solución ideal
En este caso, se usa un cuadro de diálogo accesible que:
- Se abre con el foco en el primer elemento interactivo.
- Se cierra con
Escy devuelve el foco al botón original.
<button id=»openDialog»>Abrir diálogo</button>
<div id=»dialog» role=»dialog» aria-labelledby=»dialogTitle» style=»display: none;» tabindex=»-1″>
<h2 id=»dialogTitle»>Mensaje importante</h2>
<p>Este es un cuadro de diálogo accesible.</p>
<button id=»closeDialog»>Cerrar</button>
</div>
<script>
let lastFocusedElement;
document.getElementById(«openDialog»).addEventListener(«click», function(event) {
lastFocusedElement = event.target;
let dialog = document.getElementById(«dialog»);
dialog.style.display = «block»;
dialog.focus();
});
document.getElementById(«closeDialog»).addEventListener(«click», function() {
let dialog = document.getElementById(«dialog»);
dialog.style.display = «none»;
lastFocusedElement.focus();
});
document.addEventListener(«keydown», function(event) {
if (event.key === «Escape») {
document.getElementById(«dialog»).style.display = «none»;
lastFocusedElement.focus();
}
});
</script>

✅ ¿Qué mejora?: El usuario puede cerrar el cuadro de diálogo con Esc, y el foco vuelve al botón original.
Errores comunes y cómo evitarlos
Errores frecuentes:
- No mover el foco al cuadro de diálogo o menú al abrirlo.
- Insertar el cuadro de diálogo en una posición que altera el orden lógico de navegación.
- No devolver el foco al botón original tras cerrar un cuadro de diálogo.
Cómo evitar estos errores:
- Siempre mover el foco al elemento interactivo que se abre.
- Mantener el orden lógico en la navegación por teclado.
- Proporcionar mecanismos de cierre accesibles con
Escy botones visibles.
Preguntas frecuentes sobre el fallo F85
¿Por qué es importante mover el foco en la navegación por teclado?
Porque permite a los usuarios de tecnologías asistivas interactuar de manera eficiente sin perder el contexto del contenido.
¿Cómo puedo probar si mi cuadro de diálogo es accesible?
Navega con Tab y verifica que el foco se mueve automáticamente al cuadro de diálogo al abrirse.
¿Dónde debe ir el foco después de cerrar un diálogo?
Debe regresar al botón que lo activó o a otro elemento lógico en el flujo de navegación.
¿Un cuadro de diálogo puede aparecer al final del DOM?
Sí, pero se debe usar tabindex="-1" y mover el foco manualmente con JavaScript.
¿Los menús deben cerrarse con la tecla «Esc»?
Sí, es una práctica accesible permitir el cierre de menús con la tecla Esc.
Recursos relacionados
- Guía oficial WCAG 2.1 para el fallo común F85: Incumplimiento del Criterio de Conformidad 2.4.3 debido al uso de cuadros de diálogo o menús que no están adyacentes a su control de activación en el orden de navegación secuencial
- Comprender el criterio de éxito 2.4.3: Orden de enfoque
- SCR26: Inserción de contenido dinámico en el Modelo de Objetos de Documento inmediatamente después de su elemento desencadenante
Pruebas y validación
Procedimiento
- Activa menús y cuadros de diálogo con el teclado.
- Verifica que el foco se mueve automáticamente.
- Usa
Escpara cerrarlos y confirma que el foco vuelve al botón de activación.
Resultados esperados
- ✅ Si las pruebas confirman que el usuario puede interactuar con el menú o diálogo sin problemas, entonces el contenido cumple con WCAG 2.1.
- ❌ Si alguno de los elementos anteriores no se cumple, el contenido falla el criterio 2.4.3 y debe corregirse.
Garantizar que los menús y diálogos sigan un orden lógico de navegación es esencial para la accesibilidad. Implementar estas soluciones asegura que todos los usuarios puedan navegar sin barreras.
📢 ¿Necesitas mejorar la accesibilidad de tu web? ¡Contáctanos para una auditoría gratuita! 🚀