Lección 5 de 10 · 15 min de lectura · Revisado el 26/10/2026
Componentes complejos con lector de pantalla: probar los patrones de la APG
Los componentes personalizados (pestañas, combos con autocompletado, diálogos, menús desplegables, controles deslizantes) concentran buena parte de los hallazgos graves de una auditoría, y son justo lo que las herramientas automáticas no saben evaluar. En la lección de NVDA y JAWS aprendiste los comandos; en esta aprenderás un método para evaluar cada componente: qué debería anunciar, qué teclas debe aceptar, adónde debe ir el foco y cómo comprobarlo en escritorio y en móvil. La referencia es la APG (se abre en una ventana nueva) (ARIA Authoring Practices Guide, guía de prácticas de autoría ARIA) del W3C, que describe el comportamiento que las personas usuarias esperan y que los lectores están preparados para interpretar.
El método: contrato, teclado, lector y móvil
- Identifica el patrón por su función. Antes de tocar nada, decide qué es el componente para quien lo usa: ¿un grupo de pestañas, un botón que despliega contenido (disclosure), un combo con sugerencias, un diálogo? El rol que haya elegido el equipo de desarrollo puede estar equivocado; tu referencia es lo que hace el componente, no lo que dice el código.
- Escribe el contrato esperado. Del patrón de la APG extrae tres cosas: el rol, el nombre y los estados que deben anunciarse; las teclas que deben funcionar; y adónde va el foco al abrir, cerrar o seleccionar.
- Prueba solo con teclado, sin lector, como viste en la lección de teclado y zoom. Si no se opera con teclado, ya tienes un fallo de 2.1.1 Teclado y el lector solo añadirá matices.
- Prueba con NVDA en los dos modos. Llega al componente con Tab (el lector suele pasar a modo formulario) y también en modo navegación, con flechas o con las letras de navegación rápida, activándolo con Enter o Espacio. Muchos componentes funcionan en un modo y fallan en el otro.
- Repite en móvil con VoiceOver o TalkBack: desliza hasta el componente, activa con doble toque y comprueba que los estados también se anuncian allí.
Punto clave
La APG no es normativa: un componente puede cumplir 2.1.1 Teclado y 4.1.2 Nombre, función, valor con un modelo de teclado distinto. Pero cuando el código declara un rol ARIA, por ejemplo role="tablist", el lector anuncia ese rol y la persona usuaria espera las teclas asociadas. Un rol que promete un comportamiento que no existe confunde más que no tener rol.
Tabla de referencia: qué debe anunciarse y qué teclas probar
Las palabras exactas cambian entre lectores e idiomas; lo que importa es que la información llegue. Usa esta tabla como guion de prueba y amplíala con los patrones de la APG que aparezcan en tu muestra.
| Componente | Debe anunciarse | Teclas que probar | Fallo típico |
|---|---|---|---|
| Botón desplegable (disclosure) | Nombre, «botón», contraído o expandido (aria-expanded) | Enter y Espacio; Tab hacia el contenido revelado | El estado no cambia, o el contenido se inserta al final del DOM, lejos del botón |
| Pestañas | «Pestaña», nombre, seleccionada, posición («2 de 4») | Flechas entre pestañas; Tab al panel; Inicio y Fin opcionales | Las flechas no hacen nada o no se anuncia cuál está seleccionada |
| Combo con autocompletado | «Cuadro combinado», nombre, expandido; la opción activa al moverse; número de sugerencias | Escribir, Flecha abajo, Enter, Escape | La opción resaltada visualmente no se anuncia |
| Diálogo modal | «Diálogo» y su título | Tab cicla dentro; Escape cierra; el foco vuelve al botón que lo abrió | El fondo sigue accesible con el cursor virtual; el foco se queda detrás |
| Acordeón | Botón dentro de un encabezado, contraído o expandido | Enter y Espacio | Encabezado clicable sin botón: ni operable ni anunciado |
| Tabla ordenable | Encabezado de columna con su estado de orden (aria-sort) | Enter o Espacio sobre el botón del encabezado | El orden solo se indica con una flecha visual |
| Control deslizante | «Control deslizante», nombre, valor (aria-valuetext si el número no basta) | Flechas, Inicio, Fin, Re Pág y Av Pág | El valor no se anuncia; en iOS, deslizar arriba o abajo no lo ajusta |
Ejemplo detallado: el combo con autocompletado
Es el componente que más falla y uno de los más usados: buscadores de calles y municipios en sedes electrónicas, origen y destino en webs de transporte, buscadores de tiendas. Según WAI-ARIA 1.2 (se abre en una ventana nueva) y el patrón de la APG, el campo lleva role="combobox", aria-expanded y aria-controls apuntando a una lista con role="listbox"; cada sugerencia es un role="option" y el foco permanece en el campo mientras la opción activa se comunica con aria-activedescendant.
Versión que solo funciona para quien ve la pantalla:
<input type="text" id="calle" placeholder="Calle">
<ul class="sugerencias">
<li class="activa">Calle Mayor</li>
<li>Calle Mayor Alta</li>
</ul>Versión que expone el contrato completo al árbol de accesibilidad:
<label for="calle">Calle</label>
<input id="calle" type="text" role="combobox"
aria-autocomplete="list" aria-expanded="true"
aria-controls="lista-calles"
aria-activedescendant="calle-op1">
<ul id="lista-calles" role="listbox" aria-label="Calles sugeridas">
<li id="calle-op1" role="option" aria-selected="true">Calle Mayor</li>
<li id="calle-op2" role="option" aria-selected="false">Calle Mayor Alta</li>
</ul>Guion de prueba con NVDA y el visor de voz abierto:
- Tab hasta el campo: debe anunciarse el nombre («Calle»), el rol de cuadro combinado y que es editable.
- Escribe «May»: ¿se comunica que hay sugerencias, ya sea por el cambio a expandido o por un mensaje con el número de resultados?
- Flecha abajo: ¿se lee «Calle Mayor» y, según el lector, su posición en la lista?
- Enter: ¿el valor pasa al campo, la lista se cierra y el lector confirma el valor?
- Escape: ¿se cierra la lista sin borrar lo escrito?
- En iOS con VoiceOver: ¿puedes llegar a las sugerencias deslizando y elegir una con doble toque?
Error frecuente
Dar por bueno un combo porque «las flechas mueven el resaltado». Si el lector no dice nada al pulsar Flecha abajo, la persona ciega no sabe qué opción está activa: es un fallo de 4.1.2 Nombre, función, valor. Comprueba en el visor de voz que cada pulsación produce un anuncio y que ese anuncio coincide con lo resaltado en pantalla.
Diálogos: lo que solo el lector revela
Con teclado ya habrás comprobado que el foco queda atrapado dentro del diálogo y que Escape lo cierra. Con lector añade cuatro comprobaciones:
- Al abrir: ¿se anuncia que es un diálogo y su título? El nombre suele venir de
aria-labelledbyapuntando al encabezado del diálogo. - En modo navegación: ¿puedes salir del diálogo con Flecha abajo o con H y acabar leyendo el contenido de fondo? Con el elemento
<dialog>abierto medianteshowModal(), el resto de la página queda inerte; conrole="dialog"depende dearia-modal, deinerty del soporte de cada combinación, y por eso se prueba en todas las de la línea base. - Al cerrar: ¿el foco vuelve al botón que lo abrió, o se pierde y el lector empieza a leer desde el principio de la página?
- En móvil: ¿VoiceOver o TalkBack permiten deslizar hacia el contenido de detrás?
Los fallos se registran normalmente en 2.4.3 Orden del foco (foco que se escapa o no vuelve) y en 4.1.2 Nombre, función, valor (diálogo sin rol o sin nombre); si no se puede salir con teclado, en 2.1.2 Sin trampas para el foco del teclado.
Un caso clásico: la navegación del sitio con role="menu"
Los roles menu y menubar están pensados para menús de aplicación, como los de un programa de escritorio. Cuando se aplican a la navegación principal de un sitio, el lector anuncia «barra de menú» y «elemento de menú», suele pasar a modo formulario y la persona usuaria espera moverse con flechas. Si el script no implementa ese modelo de teclado, la experiencia se rompe: las flechas no hacen nada y el comportamiento contradice lo anunciado. Para la navegación de un sitio, la APG recomienda el patrón de botones desplegables con enlaces normales.
Ejemplo
Banca en línea. El menú «Mis productos» tiene role="menubar". NVDA anuncia «barra de menú, Mis productos, submenú». Al pulsar Flecha abajo para abrirlo no ocurre nada; con Enter se despliega, pero el foco se queda en el botón y las opciones solo se alcanzan con Tab, sin que el lector indique que el submenú está abierto. Como se puede completar la tarea con Tab, no es un fallo de 2.1.1; sí lo es de 4.1.2, porque el rol y el estado expuestos no corresponden al comportamiento real. Recomendación: sustituir el menú ARIA por el patrón de navegación con botones desplegables y aria-expanded.
Criterio práctico para el informe: si en una combinación de la línea base el componente no se puede operar, es un fallo (2.1.1 o 4.1.2 según la causa). Si se puede operar pero contradice lo que anuncia, regístralo con su criterio cuando el rol o el estado expuestos sean incorrectos, y añade siempre la recomendación del patrón adecuado.
Pruébalo tú
Abre el ejemplo de pestañas de la APG en el catálogo de patrones del W3C con NVDA activo. Recórrelo con Tab y con flechas, y luego en modo navegación con Enter. Copia del visor de voz lo que se anuncia. Después repite la prueba con las pestañas de una web que uses a diario y compara ambas salidas: ¿qué falta en la segunda?
Resumen
- Evalúa cada componente con el mismo método: identificar el patrón por su función, escribir el contrato esperado, probar con teclado, con lector en ambos modos y en móvil.
- La APG describe el comportamiento esperado; no es obligatoria, pero un rol ARIA declarado promete unas teclas y unos anuncios que deben cumplirse.
- En combos, comprueba con el visor de voz que la opción activa se anuncia en cada pulsación; si no, es un fallo de 4.1.2.
- En diálogos, verifica el anuncio de rol y título, que el fondo no sea accesible en modo navegación y que el foco vuelva al disparador.
role="menu"en la navegación del sitio es una fuente habitual de problemas: recomienda el patrón de botones desplegables.
Comprueba lo que has aprendido
Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.
Matricularme · nivel 4 (49 €)