Lección 7 de 10 · 12 min de lectura · Revisado el 26/10/2026
Componentes complejos y contenido dinámico: auditar 4.1.2 y 4.1.3 patrón a patrón
La lección 6 te dio el método para evaluar 4.1.2 y 4.1.3: inventario, árbol de accesibilidad, teclado y lector. Para aplicarlo con soltura necesitas saber qué valores esperar en cada componente y en qué escenarios dinámicos suelen faltar los anuncios. Esta lección es tu tabla de referencia: los patrones más frecuentes de la ARIA Authoring Practices Guide (se abre en una ventana nueva) (APG) con su rol y sus estados, los casos frontera del nombre accesible y los mensajes de estado que más se olvidan en webs reales.
Qué esperar en cada patrón
Con la tabla siguiente puedes comparar lo que muestra el árbol de accesibilidad con lo esperado. Recuerda que el elemento nativo, cuando existe, ya aporta rol y estado: un <button> o un <input type="checkbox"> no necesitan ARIA.
| Patrón | Rol esperado | Estados y propiedades clave | Fallo típico |
|---|---|---|---|
| Botón conmutador | button | aria-pressed | Estado solo visual (icono relleno o vacío) |
| Interruptor | switch | aria-checked | Clase CSS «on» sin estado accesible |
| Desplegable o acordeón | button | aria-expanded (y aria-controls) | Valor que no se actualiza al cerrar |
| Pestañas | tablist, tab, tabpanel | aria-selected en la pestaña activa | Pestañas como enlaces sin estado |
| Diálogo modal | dialog o alertdialog | Nombre (aria-labelledby), aria-modal="true" | Capa sin rol ni nombre |
| Cuadro combinado | combobox en el campo; listbox y option | aria-expanded, aria-controls, aria-activedescendant, aria-selected | Opción resaltada que el lector no anuncia |
| Botón de menú | button; menu y menuitem | aria-haspopup, aria-expanded | role="menu" en la navegación del sitio |
| Deslizador | slider | aria-valuenow, aria-valuemin, aria-valuemax, aria-valuetext | Valor que no cambia al mover el control |
Marco (iframe) | Nativo | Nombre mediante title | Mapas o vídeos incrustados sin título |
Dos matices. En ARIA 1.2 el patrón de cuadro combinado cambió: el rol combobox va en el propio campo de texto, no en un contenedor que lo envuelve, y los componentes construidos con el patrón antiguo dan resultados irregulares según el lector. Y el rol menu promete la interacción de un menú de aplicación (flechas, foco gestionado); aplicado a un menú de navegación corriente, el rol anunciado no corresponde a cómo se usa, lo que suele generar fallos de 4.1.2 y de 2.1.1 a la vez. Consulta cada patrón en la APG antes de dictaminar.
Error frecuente
Exigir el patrón APG al pie de la letra como si fuera normativo. La APG es una guía de buenas prácticas, no parte de WCAG. Lo que exige 4.1.2 es que nombre, rol, estados y valores sean determinables y se notifiquen sus cambios. Un componente que se aparta de la APG pero comunica todo eso correctamente cumple; cita la APG como referencia de la solución, no como el requisito incumplido.
Casos frontera del nombre accesible
El algoritmo de la especificación Accessible Name and Description Computation tiene consecuencias que conviene conocer al auditar:
aria-labelledbypuede concatenar y apuntar a texto oculto. Sirve para dar contexto a botones repetidos sin cambiar lo que se ve.aria-labelno vale en cualquier elemento. ARIA 1.2 prohíbe nombrar elementos genéricos (divospansin rol) y algunos otros roles; los navegadores y lectores pueden ignorarlo. Un<div aria-label="Menú">clicable sigue sin rol ni nombre fiable.- El contenido generado por CSS cuenta. El texto de
::beforey::afterentra en el cálculo del nombre. Las fuentes de iconos que insertan caracteres de uso privado pueden producir nombres ilegibles. titleyplaceholderson el último recurso. Dan nombre, pero frágil; si es lo único que hay, revisa también 3.3.2 y 2.5.3.- Las referencias por
idno cruzan el shadow DOM (el DOM encapsulado de los componentes web). Unaria-labelledbyque apunta fuera de su raíz no funciona aunque elidexista.
Ejemplo
<!-- Incorrecto: veinte botones con el mismo nombre «Eliminar» -->
<tr><td>Certificado de empadronamiento</td>
<td><button>Eliminar</button></td></tr>
<!-- Correcto: nombre «Eliminar Certificado de empadronamiento» -->
<tr><td id="doc-17">Certificado de empadronamiento</td>
<td><button id="del-17" aria-labelledby="del-17 doc-17">Eliminar</button></td></tr>El nombre accesible empieza por la etiqueta visible, así que también se respeta 2.5.3 Etiqueta en el nombre. Ojo al veredicto: si cada botón está en su fila de una tabla bien marcada, el contexto programático ya los distingue y el ejemplo correcto es una mejora; el fallo aparece cuando nada permite saber a qué elemento afecta cada botón.
Valores y estados que el usuario establece
4.1.2 no se limita a leer: los estados y valores que el usuario puede establecer deben poder establecerse programáticamente, y sus cambios deben notificarse. En un selector personalizado, el valor elegido tiene que figurar en el árbol (no solo pintado en un span); en un deslizador, aria-valuenow debe cambiar al moverlo; en un grupo de casillas con «Seleccionar todo», el estado mixto se expresa con aria-checked="mixed". La descripción (aria-describedby), en cambio, no la exige 4.1.2: su ausencia puede afectar a 1.3.1 o a 3.3.2, no a este criterio.
Mensajes de estado en escenarios dinámicos
Recorre estos escenarios en cada auditoría; son los que más a menudo se quedan en silencio:
- Autocompletado: «5 sugerencias disponibles» cuando aparece la lista, si se muestra en pantalla un recuento o un aviso equivalente.
- Carrito y favoritos: «Producto añadido a la cesta» sin mover el foco.
- Guardado automático: «Borrador guardado», con
politey sin repetirlo cada pocos segundos. - Carga y progreso: «Cargando resultados…» y su final; para progreso medible,
role="progressbar"con valores. - Desplazamiento infinito: «Se han cargado 20 productos más».
- Validación al salir del campo: el error en línea es un mensaje de estado si el foco no se mueve a él.
- Avisos emergentes (toasts) con acción: el texto se anuncia y la acción («Deshacer») es alcanzable con teclado; si desaparece sola, revisa también 2.2.1 Tiempo ajustable.
<!-- La región existe vacía desde la carga de la página -->
<div id="aviso" role="status"></div>
<script>
// Al añadir el producto, solo se cambia el texto
document.getElementById('aviso').textContent =
'Producto añadido a la cesta. Total: 3 artículos.';
</script>
Con role="status" o aria-live, insertar el contenedor ya relleno suele no anunciarse; role="alert" se comporta mejor en ese caso, pero no conviene depender de ello. Escribir dos veces el mismo texto tampoco garantiza un segundo anuncio: si el mensaje se repite, vacía la región antes o añade un dato que cambie.
Cómo verificar lo que se anuncia
No basta con ver el atributo en el código: hay que comprobar el anuncio en la línea base. En NVDA, el Visor de voz (menú de NVDA, Herramientas) muestra por escrito todo lo que dice el lector, lo que te da una evidencia literal para el informe. En VoiceOver de macOS, el panel de subtítulos cumple la misma función. En las herramientas de desarrollo, comprueba que el contenedor con role o aria-live está en el DOM antes de la acción, y no se crea con ella.
Pruébalo tú
Abre una tienda en línea, activa NVDA con el Visor de voz y añade un producto a la cesta sin mover el foco. Copia lo que aparece en el Visor de voz. Después abre las pestañas de una ficha de producto o un acordeón de preguntas frecuentes y, en el panel Accessibility de Chrome, anota rol, nombre y estado antes y después de activarlo. Compáralo con la tabla de esta lección.
Resumen
- Cada patrón tiene un rol y unos estados esperados; compáralos con el árbol de accesibilidad y usa la APG como referencia de la solución, no como requisito normativo.
- El nombre accesible tiene trampas:
aria-labelen elementos genéricos, contenido generado por CSS,titlecomo único nombre y referencias que no cruzan el shadow DOM. - 4.1.2 incluye establecer y notificar valores y estados, no la descripción.
- Autocompletados, carritos, guardados, cargas, desplazamiento infinito, validación en línea y toasts son los mensajes de estado que más se olvidan.
- Verifica los anuncios con el Visor de voz de NVDA o el panel de subtítulos de VoiceOver, y comprueba que la región viva existe antes del cambio.
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 €)