Skip to main content

Acerca de esta regla de accesibilidad

El atributo aria-hidden="true" le dice a las tecnologías de asistencia que ignoren un elemento y todos sus descendientes. Esto es útil para ocultar contenido puramente decorativo — como fuentes de iconos o elementos visuales redundantes — que saturarían la experiencia del lector de pantalla. Sin embargo, surge un problema serio cuando elementos enfocables como enlaces, botones, campos de formulario, o elementos con tabindex="0" existen dentro de un contenedor con aria-hidden="true".

Cuando esto sucede, los usuarios de teclado aún pueden usar Tab para llegar a esos elementos, pero los lectores de pantalla no los anunciarán. El usuario aterriza en lo que se siente como un control invisible y sin etiqueta. No tienen forma de saber qué es el elemento o qué hace. Esto afecta a usuarios ciegos, usuarios sordociegos, usuarios con baja visión que dependen de lectores de pantalla, y usuarios con discapacidades motoras que navegan exclusivamente por teclado.

También es importante entender que aria-hidden="false" en un descendiente no anula aria-hidden="true" en un ancestro. Una vez que un padre está oculto del árbol de accesibilidad, todos los hijos permanecen ocultos independientemente de su propio valor de aria-hidden. Cualquier hijo enfocable dentro de ese subárbol aún crea el mismo problema.

Criterios de éxito WCAG relacionados

Esta regla se relaciona principalmente con el Criterio de Éxito WCAG 4.1.2: Nombre, Función, Valor (Nivel A). Este criterio requiere que para todos los componentes de la interfaz de usuario, el nombre y la función puedan determinarse programáticamente, y los estados, propiedades y valores puedan establecerse programáticamente. Un elemento enfocable dentro de un contenedor con aria-hidden="true" viola esto porque su nombre y función se eliminan de la API de accesibilidad mientras permanece accesible vía teclado — haciendo imposible que las tecnologías de asistencia transmitan su propósito. Esta regla se marca a través de WCAG 2.0, 2.1 y 2.2 en Nivel A, así como en las directrices de Trusted Tester, EN 301 549 y RGAA.

Cómo solucionarlo

Hay varias estrategias para resolver este problema:

  1. Eliminar aria-hidden="true" de elementos que contengan hijos enfocables, si esos hijos necesitan ser interactivos.
  2. Eliminar elementos enfocables de dentro del contenedor con aria-hidden="true" si toda la sección está realmente destinada a estar oculta.
  3. Hacer que los elementos enfocables no sean enfocables añadiendo tabindex="-1" a enlaces, botones, u otros elementos interactivos dentro del contenedor oculto.
  4. Usar el atributo disabled en controles de formulario (no aria-disabled, que no previene realmente el foco).
  5. Ocultar elementos con CSS usando display: none o visibility: hidden, que los elimina tanto del árbol de accesibilidad como del orden de foco simultáneamente.

Si necesitas ocultar contenido de las tecnologías de asistencia, asegúrate de que el significado y funcionalidad equivalentes estén aún disponibles a través de otros medios accesibles.

Ejemplos

Incorrecto: enlace enfocable dentro de aria-hidden="true"

El enlace se elimina del árbol de accesibilidad pero aún recibe el foco del teclado.

<div aria-hidden="true">
  <a href="/home">Home</a>
</div>

Incorrecto: enlace enfocable fuera de pantalla dentro de aria-hidden="true"

Mover un enlace fuera de pantalla no lo elimina del orden de foco.

<div aria-hidden="true">
  <a href="/" style="position:absolute; top:-999em">Link</a>
</div>

Incorrecto: usar aria-disabled en lugar de disabled

El atributo aria-disabled no previene realmente que el input reciba el foco.

<div aria-hidden="true">
  <input aria-disabled="true" />
</div>

Incorrecto: elemento con tabindex="0" y aria-hidden="true"

Añadir tabindex="0" hace que un elemento normalmente no enfocable sea enfocable, creando un conflicto con aria-hidden="true".

<p tabindex="0" aria-hidden="true">Some descriptive text</p>

Incorrecto: intentar anular aria-hidden en un descendiente

Establecer aria-hidden="false" en un hijo no lo vuelve a exponer cuando un padre tiene aria-hidden="true". El botón permanece oculto de las tecnologías de asistencia pero aún recibe el foco.

<div aria-hidden="true">
  <div aria-hidden="false">
    <button>Submit</button>
  </div>
</div>

Incorrecto: <summary> enfocable dentro de aria-hidden="true"

El elemento <summary> es enfocable de forma nativa.

<details aria-hidden="true">
  <summary>More info</summary>
  <p>Additional details here.</p>
</details>

Correcto: contenido no enfocable dentro de aria-hidden="true"

Un párrafo sin elementos interactivos es seguro de ocultar.

<p aria-hidden="true">Decorative description text</p>

Correcto: elementos enfocables ocultos con CSS display: none

Usar display: none elimina el enlace tanto del orden de foco como del árbol de accesibilidad.

<div aria-hidden="true">
  <a href="/" style="display:none">Link</a>
</div>

Correcto: elementos enfocables hechos no enfocables con tabindex="-1"

Añadir tabindex="-1" elimina el botón del orden de tabulación.

<div aria-hidden="true">
  <button tabindex="-1">Close</button>
</div>

Correcto: input de formulario correctamente deshabilitado con el atributo disabled

El atributo disabled previene que el input reciba el foco completamente.

<input disabled aria-hidden="true" />

Correcto: eliminar aria-hidden y mantener los elementos interactivos

Si el contenido necesita ser enfocable, simplemente no lo ocultes de las tecnologías de asistencia.

<div>
  <a href="/home">Home</a>
</div>

Ayúdanos a mejorar nuestras guías

¿Te ha sido útil esta guía?

Detecta problemas de accesibilidad automáticamente

Rocket Validator escanea miles de páginas con Axe Core y el W3C Validator, encontrando problemas de accesibilidad en todo tu sitio web.

¿Listo para validar tus sitios?
Inicia tu prueba gratuita hoy.