Addaw, ir a inicio Donar

Lección 9 de 10 · 12 min de lectura · Revisado el 26/10/2026

HTML válido y robusto: identificadores, anidamiento y el fin de 4.1.1

Todo lo visto en el curso parte de un supuesto: que el navegador construye el árbol de accesibilidad a partir de un HTML que dice lo que pretendemos. Cuando el marcado tiene errores, el navegador no se detiene: los corrige a su manera, y el resultado puede ser un árbol distinto del que imaginábamos. Esta lección explica qué pasó con el criterio 4.1.1 Procesamiento, por qué la validez sigue importando aunque ese criterio ya no exista en WCAG 2.2 y cuáles son los errores de marcado que de verdad rompen la accesibilidad: identificadores duplicados, anidamientos imposibles y atributos mal escritos.

Qué pasó con 4.1.1 Procesamiento

En WCAG 2.0 y 2.1, el criterio 4.1.1 (nivel A) pedía que el marcado no tuviera errores de procesamiento: elementos con etiquetas de apertura y cierre completas, anidados según su especificación, sin atributos duplicados y con identificadores únicos. Tenía sentido cuando cada navegador y cada tecnología de apoyo interpretaban el HTML mal formado de forma distinta. Hoy el estándar HTML define con precisión cómo debe recuperarse el navegador de cada error, y las tecnologías de apoyo ya no leen el código fuente, sino el árbol de accesibilidad que construye el navegador.

Por eso WCAG 2.2 marca 4.1.1 como obsoleto y retirado, y el W3C añadió a WCAG 2.0 y 2.1 una nota que indica que, para contenido en HTML o XML, debe considerarse siempre cumplido. Hay un matiz importante para quien trabaja en España: la EN 301 549 v3.2.1 (PDF, se abre en una ventana nueva), a la que remite el RD 1112/2018 (PDF, se abre en una ventana nueva), se basa en WCAG 2.1 y sigue incluyendo el requisito correspondiente (9.4.1.1). Cómo tratarlo en una auditoría depende de la metodología que se aplique; lo verás en el nivel 4. Lo que no cambia es esto: los problemas reales que antes se recogían en 4.1.1 se siguen evaluando, ahora bajo 1.3.1 Información y relaciones y 4.1.2 Nombre, función, valor.

Punto clave

Un error de validación no es, por sí solo, un fallo de accesibilidad. Un error de validación que cambia lo que recibe la persona (un campo que pierde su etiqueta, una lista que deja de serlo, un botón sin nombre) sí lo es, y se registra en el criterio que resulta afectado.

Identificadores duplicados

Es el error de marcado con más consecuencias, porque muchas relaciones de accesibilidad se construyen con id: <label for>, aria-labelledby, aria-describedby, aria-controls, headers en tablas y los enlaces internos como el de salto al contenido. Cuando dos elementos comparten id, el navegador usa el primero que encuentra y la relación del segundo se rompe en silencio.

<!-- El formulario de suscripción aparece en la cabecera y en el pie -->
<label for="email">Correo electrónico</label>
<input id="email" type="email">
…
<label for="email">Correo electrónico</label>
<input id="email" type="email">

Las dos etiquetas apuntan al primer campo. El segundo queda sin nombre accesible: el lector anuncia «edición» sin más y, además, al pulsar sobre la segunda etiqueta el foco salta al primer campo. Se incumplen 1.3.1 y 4.1.2.

Las causas típicas son siempre las mismas: componentes que se repiten en la página (tarjetas, acordeones, formularios de búsqueda en cabecera y pie), menús que se pintan dos veces (versión de escritorio y versión móvil ocultando una con CSS) e identificadores escritos a mano en plantillas que luego se reutilizan. La solución es generar los identificadores a partir de algo único (el número de registro, un contador, las utilidades de identificadores únicos de cada framework) y no duplicar componentes completos para cada tamaño de pantalla.

Anidamientos que el navegador no puede respetar

HTML define qué puede ir dentro de qué. Cuando el código lo incumple, el analizador del navegador reorganiza el árbol y el resultado ya no coincide con el código fuente:

  • Bloques dentro de un párrafo. <p><div>…</div></p> no existe: el navegador cierra el párrafo antes del <div> y deja un párrafo vacío detrás.
  • Contenido suelto dentro de una tabla. El texto o los elementos colocados entre <tr> y <td> se sacan fuera de la tabla, por delante de ella.
  • Enlaces dentro de enlaces. Un <a> dentro de otro <a> cierra el primero: el resultado son dos enlaces seguidos, con nombres que no esperabas.
  • Hijos incorrectos en listas. Un <div> entre <ul> y <li> se mantiene en el DOM, pero rompe la semántica de lista en varias combinaciones de navegador y lector, como vimos en la lección de listas. En <dl>, en cambio, sí está permitido un <div> que agrupe cada pareja de <dt> y <dd>.

Hay un caso que el analizador no corrige y que es aún peor: los elementos interactivos dentro de otros elementos interactivos. Un <button> dentro de un <a>, un enlace dentro de un botón o una casilla de verificación dentro de un enlace no son HTML válido y cada navegador y cada lector los exponen de forma distinta: el control interior puede perder su rol, quedar inaccesible con el teclado o fundir su nombre con el del exterior.

Error frecuente

<a href="/producto/123" class="tarjeta">
  <h3>Silla ergonómica</h3>
  <button>Añadir a favoritos</button>
</a>

La tarjeta entera es un enlace que contiene un botón. Corrección: el enlace solo en el título (y, si se quiere toda la tarjeta pulsable, el área ampliada con CSS que vimos en la lección de patrones) y el botón como hermano, no como hijo, del enlace.

Atributos mal escritos o con valores inválidos

El navegador ignora los atributos que no reconoce y los valores que no entiende, sin avisar. Algunos ejemplos reales que pasan desapercibidos en una revisión visual:

CódigoQué ocurreCorrección
aria-labeledby="t1"Se ignora: el nombre correcto tiene dos elesaria-labelledby="t1"
<label for="nombre"> sin ningún id="nombre"La etiqueta no se asocia y el campo queda sin nombreHacer coincidir for e id
aria-hidden="yes"Valor no válido; no oculta nadaaria-hidden="true"
lang="es_ES"Código de idioma no válido (el separador de BCP 47 es el guion)lang="es" o lang="es-ES"
<table summary="…">, <center>, <font>Obsoletos: sin efecto o con efecto solo visual<caption> o párrafo previo; CSS para el aspecto

Ninguno de estos errores se ve en pantalla. Todos cambian lo que recibe la persona usuaria de tecnologías de apoyo, y por eso hay que buscarlos con herramientas.

Cómo detectarlo

El validador del W3C

El Nu Html Checker del W3C analiza una dirección, un archivo o un fragmento pegado. Para sitios que construyen la página con JavaScript, valida el DOM ya generado: en las herramientas de desarrollo, copia el elemento <html> (opción de copiar el HTML externo) y pégalo en la entrada de texto del validador. No persigas el cero absoluto: céntrate en identificadores duplicados, anidamientos de elementos interactivos, hijos no permitidos en listas y tablas, y atributos ARIA desconocidos o con valores inválidos.

Comprobaciones rápidas en el navegador

Para localizar identificadores duplicados en la página que tienes abierta, pega esto en la consola de las herramientas de desarrollo:

const ids = [...document.querySelectorAll('[id]')].map(e => e.id);
console.log(ids.filter((id, i) => ids.indexOf(id) !== i));

Las herramientas automáticas como axe o WAVE detectan también parte de estos errores (identificadores duplicados usados por ARIA o por etiquetas, atributos ARIA inválidos, marcos sin título). Y el panel de accesibilidad del navegador, que conociste en la lección sobre el árbol de accesibilidad, es la prueba definitiva: si el árbol muestra el rol, el nombre y la relación que esperabas, el marcado cumple su función aunque el validador proteste por algo menor.

Pruébalo tú

Abre la portada de tu web o de un sitio público que uses a menudo. Ejecuta el fragmento anterior en la consola y anota los identificadores repetidos. Después pasa la dirección por el validador del W3C y filtra mentalmente: ¿cuántos errores afectan a etiquetas, relaciones ARIA, listas, tablas o elementos interactivos? Esos son los que tendrías que corregir primero.

Resumen

  • WCAG 2.2 retira 4.1.1 Procesamiento; la EN 301 549 v3.2.1 aún lo recoge (9.4.1.1) y su tratamiento depende de la metodología aplicada.
  • Los errores de marcado que cambian el árbol de accesibilidad se evalúan bajo 1.3.1 y 4.1.2.
  • Los identificadores duplicados rompen en silencio label for, aria-labelledby, aria-describedby y headers.
  • Nunca anides elementos interactivos dentro de otros, y respeta qué hijos admiten listas y tablas.
  • Valida el DOM generado, busca duplicados desde la consola y confirma siempre en el árbol de accesibilidad.

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.