Acerca de este problema HTML
El atributo aria-labelledby acepta un valor IDREFS — una lista separada por espacios de uno o más valores id que hacen referencia a otros elementos en el documento. El validador espera que cada ID en la lista no esté vacío y contenga al menos un carácter que no sea espacio en blanco. Cuando el atributo se establece como una cadena vacía (aria-labelledby=""), viola esta restricción y desencadena el error de validación.
Este problema surge comúnmente en sistemas de plantillas y frameworks de JavaScript donde una variable destinada a contener una referencia de ID se resuelve como una cadena vacía. Por ejemplo, una plantilla como aria-labelledby="{{ labelId }}" producirá un atributo vacío si labelId es indefinido o está en blanco.
Por qué esto importa
El atributo aria-labelledby es uno de los métodos de mayor prioridad para calcular el nombre accesible de un elemento. Según el algoritmo de cálculo de nombres accesibles, aria-labelledby anula todas las demás fuentes de nombres — incluyendo contenido de texto visible, aria-label, y el atributo title. Cuando aria-labelledby está presente pero vacío o roto, los lectores de pantalla pueden calcular el nombre accesible del enlace como vacío, haciendo efectivamente que el enlace sea invisible o sin sentido para los usuarios de tecnología asistiva. Un enlace sin nombre accesible es una barrera significativa de accesibilidad: los usuarios no pueden determinar hacia dónde va el enlace o qué hace.
Más allá de la accesibilidad, un aria-labelledby vacío también indica HTML inválido según tanto el estándar WHATWG HTML living standard como la especificación WAI-ARIA, que definen el tipo IDREFS como que requiere al menos un token válido.
Cómo solucionarlo
Tienes varias opciones dependiendo de tu situación:
-
Hacer referencia a un ID válido — Apunta
aria-labelledbyalidde un elemento existente cuyo contenido de texto debe servir como el nombre accesible del enlace. -
Eliminar el atributo y usar texto de enlace visible — Si el enlace ya contiene texto descriptivo,
aria-labelledbyes innecesario. -
Usar
aria-labelen su lugar — Para enlaces de solo iconos donde no existe un elemento de etiqueta visible,aria-labelproporciona un nombre accesible conciso directamente en el elemento. -
Renderizar el atributo condicionalmente — En plantillas, usa lógica condicional para omitir completamente
aria-labelledbycuando no hay un ID válido que referenciar, en lugar de renderizar un valor vacío.
Ejemplos
Inválido: aria-labelledby vacío
Esto desencadena el error de validación porque el valor del atributo no contiene caracteres que no sean espacios en blanco.
<a href="/report" aria-labelledby=""></a>
Inválido: aria-labelledby con solo espacios en blanco
Un valor que contiene solo espacios es igualmente inválido — IDREFS requiere al menos un token real.
<a href="/report" aria-labelledby=" "></a>
Corregido: haciendo referencia a un elemento existente por id
El atributo aria-labelledby apunta a un <span> cuyo contenido de texto se convierte en el nombre accesible del enlace.
<a href="/report" aria-labelledby="report-link-text">
<svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
<span id="report-link-text">Ver reporte</span>
Corregido: haciendo referencia a múltiples IDs
Puedes concatenar texto de múltiples elementos listando sus IDs separados por espacios. El nombre accesible se construye uniendo el texto referenciado en orden.
<span id="action">Aprende más:</span>
<span id="subject">Manzanas</span>
<a href="/apples" aria-labelledby="action subject">
<svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
En este caso, el nombre accesible calculado es “Aprende más: Manzanas”.
Corregido: usando texto de enlace visible en su lugar
Cuando el enlace ya contiene texto descriptivo, no se necesita ningún atributo ARIA. Este es el enfoque más simple y robusto.
<a href="/report">Ver reporte</a>
Corregido: usando aria-label para un enlace de solo icono
Cuando no hay un elemento de etiqueta visible separado que referenciar, aria-label proporciona el nombre accesible directamente.
<a href="/search" aria-label="Buscar">
<svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
Corregido: renderizado condicional en una plantilla
Si estás usando un motor de plantillas, incluye condicionalmente el atributo solo cuando existe un valor. La sintaxis exacta varía por framework, pero aquí está la idea general:
<!-- En lugar de siempre renderizar el atributo: -->
<!-- <a href="/report" aria-labelledby="{{ labelId }}"> -->
<!-- Solo renderízalo cuando labelId tenga un valor: -->
<!-- <a href="/report" {{#if labelId}}aria-labelledby="{{labelId}}"{{/if}}> -->
Esto previene el problema del atributo vacío en su origen en lugar de parchearlo después del hecho.
Encuentra problemas como este automáticamente
Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.
Más información: