Lección 3 de 10 · 14 min de lectura · Revisado el 26/10/2026
Cómo ve la página un motor de reglas: DOM, árbol de accesibilidad y momento del análisis
Como vimos en la lección anterior, una herramienta automática solo puede comprobar lo que es verificable mecánicamente. Para interpretar sus resultados hace falta saber, además, qué ve exactamente: no el código del equipo de desarrollo ni la pantalla de la persona usuaria, sino una fotografía del DOM y de los estilos calculados en un instante concreto. Esta lección abre la caja: qué analiza el motor, cómo está construida una regla, cómo calcula el nombre accesible y el contraste, y qué se le escapa. Con esto entenderás el origen de muchos falsos positivos y negativos.
Del código fuente al árbol de accesibilidad
Entre lo que envía el servidor y lo que recibe un lector de pantalla hay cuatro capas, y cada herramienta trabaja sobre una distinta:
- Código fuente: el HTML que devuelve el servidor (lo que ves con Ctrl + U). En una aplicación de una sola página puede ser poco más que un
<div id="app">vacío. - DOM: el árbol de nodos que construye el navegador tras analizar el HTML y ejecutar JavaScript. Es lo que muestra el panel Elementos y cambia con cada interacción.
- Estilos calculados: el resultado final de la cascada CSS para cada elemento (color, tamaño, visibilidad, posición).
- Árbol de accesibilidad: lo que el navegador expone a las tecnologías de apoyo mediante las API de accesibilidad del sistema operativo (UI Automation e IAccessible2 en Windows, NSAccessibility en macOS, AT-SPI en Linux): rol, nombre, estado y relaciones de cada objeto.
Los motores de reglas como axe-core o el de IBM Equal Access se ejecutan como JavaScript dentro de la página. Leen el DOM y los estilos calculados y, con ellos, reconstruyen su propia aproximación al árbol de accesibilidad: no consultan el que genera el navegador. Por eso el nombre accesible que calcula axe puede no coincidir, en casos límite, con el que muestra el panel Accessibility de Chrome o con lo que anuncia NVDA. El validador Nu HTML, en cambio, analiza el código fuente cuando le das una URL: no ejecuta JavaScript y no ve el DOM final.
Ejemplo
El portal de cita previa de un organismo está hecho con un framework de JavaScript. Su código fuente es este:
<body>
<div id="app"></div>
<script src="/assets/main.js"></script>
</body> Validado por URL en el Nu HTML Checker, no aparece ningún problema del formulario, porque no existe en el código servido. Para validarlo hay que copiar el HTML del DOM generado (en el panel Elementos, «Copiar elemento») y pegarlo en la entrada de texto del validador. axe sí analiza el formulario, porque trabaja sobre el DOM renderizado.
Infografía · Proceso
Cómo analiza una página un motor de reglas
Del DOM renderizado al resultado: cada paso explica un tipo de falso positivo o negativo
- Paso 1: 1. Cargar y renderizarEl navegador construye el DOM, ejecuta JavaScript y calcula los estilos
- Paso 2: 2. Fijar el estadoLo que no esté abierto, cargado o visible en ese instante no se analiza
- Paso 3: 3. Seleccionar elementosCada regla elige a qué elementos se aplica; si no hay ninguno, es inaplicable
- Paso 4: 4. Ejecutar comprobacionesAtributos, nombre accesible, roles y contraste calculado; nunca el significado
- Paso 5: 5. ClasificarPasa, falla, necesita revisión o inaplicable, elemento a elemento
- Paso 6: 6. InformarRegla, selector, código y criterio WCAG etiquetado, pendiente de verificar
Leer la infografía como texto
Proceso de seis pasos en secuencia. Paso 1, cargar y renderizar: el navegador construye el DOM, ejecuta JavaScript y calcula los estilos. Paso 2, fijar el estado: el análisis es una fotografía, y lo que no esté abierto, cargado o visible en ese instante no se analiza. Paso 3, seleccionar elementos: cada regla elige a qué elementos se aplica y, si no hay ninguno, el resultado es inaplicable. Paso 4, ejecutar comprobaciones: atributos, nombre accesible calculado, roles y contraste a partir de los estilos, sin evaluar el significado. Paso 5, clasificar cada elemento como pasa, falla, necesita revisión o inaplicable. Paso 6, informar: identificador de la regla, selector, fragmento de código y criterio WCAG con el que está etiquetada la regla, que el auditor debe verificar.
Anatomía de una regla
Todas las reglas automáticas siguen el mismo esquema, tanto en axe-core como en el formato ACT Rules del W3C que vimos en la primera lección:
- Aplicabilidad: a qué elementos se aplica la regla. Por ejemplo,
image-altse aplica a los elementosimgque no están ocultos. Si no hay ninguno, el resultado es «inaplicable». - Comprobaciones: en axe se agrupan en tres tipos: any (basta con que pase una: el
imgtienealt, oaria-label, oaria-labelledbyválido, o rol de presentación), all (deben pasar todas) y none (no debe darse ninguna, como un atributo ARIA prohibido). - Resultado por elemento: pasa, falla o, si alguna comprobación no puede decidir, «necesita revisión» (incomplete).
Lo importante es lo que no forma parte de ninguna comprobación: el significado. La regla button-name pasa si el botón tiene texto interno, aria-label, aria-labelledby que apunte a texto o title. Un botón llamado «Botón1» o «Click» pasa exactamente igual que uno llamado «Pedir cita».
Cómo calcula el nombre accesible
El nombre accesible se calcula según la especificación del W3C Accessible Name and Description Computation (accname 1.2) y las reglas de cada lenguaje (HTML-AAM). Simplificando, el orden de prioridad es:
aria-labelledby(aunque el texto referenciado esté oculto).aria-label.- El mecanismo nativo del lenguaje:
labelasociado,alt,caption,legend,valuede un botón de tipoinput. - El contenido del propio elemento, cuando el rol lo permite (botones, enlaces, encabezados, celdas).
titley, como último recurso en los campos,placeholder.
La consecuencia práctica es que lo que va primero sustituye a lo que va después. Un aria-label oculta el texto visible del botón, y la herramienta solo comprueba que el nombre existe:
<!-- Pasa button-name, pero el nombre no contiene el texto visible -->
<button type="submit" aria-label="Enviar formulario">Buscar</button>
<!-- Correcto: el nombre sale del texto visible -->
<button type="submit">Buscar</button> Quien usa control por voz dirá «pulsar Buscar» y no pasará nada, porque el nombre es «Enviar formulario»: incumple 2.5.3 Etiqueta en el nombre. axe tiene una regla para este caso (label-content-name-mismatch), pero es experimental y viene desactivada por defecto, así que en la práctica es un falso negativo.
Punto clave
Cuando dudes de un resultado sobre nombres, no discutas con la herramienta: abre el panel Accessibility de Chrome (o el Inspector de accesibilidad de Firefox), selecciona el elemento y mira el nombre calculado por el navegador y de qué atributo procede. Ese es el nombre que recibirán las tecnologías de apoyo.
Cómo calcula el contraste
Para la regla de contraste, el motor obtiene el color calculado del texto (incluida su opacidad) y busca qué hay detrás: recorre los elementos apilados en ese punto y combina las capas semitransparentes hasta llegar a un fondo opaco. Después calcula la luminancia relativa de ambos colores con la fórmula de WCAG 2.x y decide el umbral según el tamaño: 4,5:1 para texto normal y 3:1 para texto grande, que WCAG define como 18 puntos o 14 puntos en negrita (unos 24 px y 18,66 px CSS).
El cálculo funciona bien con colores planos. Cuando detrás del texto hay una imagen, un degradado, un pseudoelemento, una sombra de texto o un elemento superpuesto, el motor no puede asegurar el color de fondo y lo deja como «necesita revisión». También mide solo el estado presente en el momento del análisis: si quieres medir el foco o el paso del puntero, tienes que forzar ese estado (en Chrome, panel Estilos, botón :hov, «Forzar estado del elemento») y volver a analizar. En los casos límite de tamaño, como un texto de 18 px en negrita, confirma a mano el tamaño calculado antes de aceptar el umbral que ha aplicado la herramienta.
Las zonas ciegas: lo que el motor no llega a ver
Todo lo que no está en el DOM, o en el estado adecuado, cuando pulsas «Analizar», no existe para la herramienta.
| Situación | Qué hace el motor | Qué debes hacer |
|---|---|---|
| Menús, modales, errores de formulario o resultados que aparecen al interactuar | Solo los analiza si están abiertos en ese momento; los elementos con display: none se ignoran | Poner la página en cada estado de la muestra y analizar de nuevo |
| Contenido cargado de forma diferida (scroll infinito, carga perezosa) | Analiza solo lo que ya se ha cargado | Desplazarse hasta el final o provocar la carga antes de analizar |
| Iframes, sobre todo de terceros (mapas, chats, pasarelas de pago) | Las extensiones intentan inyectar el motor en cada marco, pero restricciones de seguridad o de carga pueden dejarlos fuera | Comprobar en los resultados que el contenido del marco se ha analizado |
| Componentes con Shadow DOM | axe recorre el Shadow DOM abierto; el cerrado no es accesible desde JavaScript | Revisar a mano los componentes con raíz cerrada |
canvas, WebGL, vídeo y audio | No ve su contenido; como mucho, si existe un contenido alternativo o una pista de subtítulos | Evaluación manual completa |
| Diseño adaptable | Analiza el diseño del tamaño de ventana actual | Repetir en anchura de móvil (320 px CSS) y de escritorio |
| Criterios que comparan páginas (3.2.3, 3.2.4, 3.2.6) | Analiza cada página por separado y no compara | Comparar la muestra a mano |
Error frecuente
Analizar solo el estado inicial de cada página. El informe dice «sin violaciones automáticas» en la página de pedir cita, pero nadie abrió el calendario, nadie envió el formulario vacío y nadie desplegó el menú en anchura de móvil. Al repetir el análisis en esos tres estados aparecen campos sin nombre, un botón de cierre vacío y un mensaje de error con contraste 2,8:1.
Pruébalo tú
- Abre una web que tenga un menú desplegable o una ventana modal y ejecuta axe DevTools en el estado inicial. Anota el número de violaciones y de elementos por revisar.
- Abre el menú o la modal y vuelve a analizar. Compara las cifras.
- En Chrome, abre las herramientas de desarrollo, selecciona un botón en el panel Elementos y abre la pestaña Accessibility: observa el nombre calculado y de qué atributo procede.
Resumen
- Los motores de reglas analizan el DOM y los estilos calculados en un instante y reconstruyen su propia versión del árbol de accesibilidad; el validador Nu analiza el código servido.
- Cada regla tiene una aplicabilidad y unas comprobaciones (any, all, none); ninguna evalúa el significado.
- El nombre accesible sigue un orden de prioridad (aria-labelledby, aria-label, mecanismo nativo, contenido, title): lo primero sustituye a lo siguiente y puede provocar fallos de 2.5.3 que la herramienta no ve.
- El contraste se calcula bien sobre colores planos; imágenes, degradados, superposiciones y estados exigen medición manual.
- Estados de interacción, carga diferida, iframes, Shadow DOM cerrado, canvas, diseño adaptable y comparaciones entre páginas son zonas ciegas que hay que cubrir a mano.
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 €)