Addaw, ir a inicio Donar

Lección 7 de 10 · 13 min de lectura · Revisado el 26/10/2026

Ocultar, anular y desactivar: aria-hidden, role="none", inert y aria-disabled

Tan importante como añadir semántica es saber retirarla. Ocultar al lector un icono decorativo, anular la semántica de una tabla usada para maquetar, dejar fuera de uso el fondo de una ventana modal o indicar que un botón todavía no está disponible son operaciones cotidianas, y cada una tiene su herramienta. Confundirlas produce las paradas de foco mudas y el contenido desaparecido que mencionamos al explicar la regla 4. La ocultación con CSS se trata en el curso N3-C6; aquí nos centramos en lo que hace cada mecanismo con el árbol de accesibilidad, con el foco y con la interacción.

Tres preguntas para cada mecanismo

Para elegir bien, pregúntate de cada técnica: ¿se ve en pantalla?, ¿está en el árbol de accesibilidad (la percibe el lector)? y ¿se puede enfocar y usar?

Mecanismo¿Se ve?¿Está en el árbol?¿Se puede enfocar y usar?
Atributo hidden o display: noneNoNoNo
visibility: hiddenNoNoNo
Clase «solo para lectores» (texto visualmente oculto)NoSíSí, si es enfocable
aria-hidden="true"SíNo, ni él ni sus descendientesSí (de ahí el peligro)
inertSíNoNo
role="none" o role="presentation"SíPierde su rol; su contenido sigueNo cambia nada
disabled (nativo)SíSí, como no disponibleNo; sale del orden de tabulación
aria-disabled="true"SíSí, como no disponibleSe enfoca; bloquear la acción es tarea tuya

Infografía · Conceptos clave

Ocultar, anular y desactivar: qué hace cada mecanismo

Siete herramientas que se confunden a menudo, según se vean, estén en el árbol o reciban el foco

  • hidden / display: noneDesaparece para todos: no se ve, no está en el árbol y no recibe foco.
  • Texto solo para lectoresNo se ve, pero el lector lo lee; si es enfocable, recibe el foco.
  • aria-hidden="true"Se ve y se enfoca, pero no está en el árbol: nunca en enfocables.
  • inertSe ve, pero sin foco, sin clics y fuera del árbol. Retíralo al cerrar.
  • role="none"Quita el rol, no el contenido. Se ignora en elementos enfocables.
  • disabledNo disponible y fuera del orden de tabulación, sin eventos ni envío.
  • aria-disabled="true"Se anuncia no disponible y sigue enfocable: el bloqueo lo programas tú.
ADDAW · Cursos de accesibilidad
Leer la infografía como texto

Siete tarjetas, una por mecanismo. Atributo hidden o display none: desaparece para todos; ni se ve, ni está en el árbol de accesibilidad, ni recibe el foco. Texto solo para lectores: no se ve, pero el lector lo lee, y si es enfocable recibe el foco. aria-hidden igual a true: se ve y se puede enfocar, pero no está en el árbol; nunca debe usarse en elementos enfocables. inert: se ve, pero no admite foco ni clics y sale del árbol; hay que retirarlo al cerrar. role none: quita el rol pero no el contenido, y se ignora en elementos enfocables. disabled nativo: se anuncia como no disponible y sale del orden de tabulación, sin eventos ni envío. aria-disabled igual a true: se anuncia como no disponible y sigue siendo enfocable, pero el bloqueo de la acción lo programa quien desarrolla.

aria-hidden: ocultar solo al lector

aria-hidden="true" retira el elemento y todos sus descendientes del árbol de accesibilidad, sin cambiar nada en pantalla ni en el teclado. Sus usos legítimos son concretos:

  • Iconos decorativos o redundantes junto a un texto que ya dice lo mismo.
  • Contenido duplicado: la miniatura y el titular de una tarjeta que enlazan al mismo sitio, cuando uno de los dos enlaces se retira del orden de tabulación con tabindex="-1" y del árbol con aria-hidden.
  • Caracteres de adorno (flechas, viñetas dibujadas con texto, separadores «/»).
<!-- Correcto: el icono es decorativo, el nombre lo da el texto -->
<button type="button">
  <svg aria-hidden="true" viewBox="0 0 24 24">…</svg>
  Descargar certificado
</button>

<!-- Correcto: la flecha es adorno -->
<a href="/tramites">Ver todos los trámites <span aria-hidden="true">→</span></a>

Y sus límites, que conviene saber de memoria:

  • No lo pongas en nada enfocable ni en un contenedor con enfocables dentro (regla 4). Antes de ocultar un bloque, busca enlaces, botones y campos en su interior.
  • No se puede «deshacer» desde dentro. Poner aria-hidden="false" en un descendiente de un elemento oculto no lo vuelve a mostrar de forma fiable. Si una parte debe percibirse, saca el atributo del contenedor y ponlo solo en lo que quieras ocultar.
  • Nunca en <body> ni en grandes zonas de forma permanente: ARIA in HTML lo desaconseja expresamente en <body>, y en la práctica equivale a dejar la página vacía para el lector.
  • El texto oculto sigue sirviendo para nombrar. Un elemento con aria-hidden puede ser el destino de un aria-labelledby o aria-describedby; su texto se usa igualmente, como viste en la lección sobre roles y estados.

role="none" y role="presentation": quitar el rol, no el contenido

Son sinónimos (none se añadió en ARIA 1.1 por ser un nombre más claro). Eliminan la semántica del elemento, pero su texto y sus descendientes siguen en el árbol. Se usan cuando un elemento con semántica se emplea solo por motivos visuales: la tabla de maquetación de un boletín por correo electrónico o de un gestor de contenidos antiguo, o la lista que solo sirve para colocar elementos en fila.

Hay dos reglas de funcionamiento que explican casi todas las sorpresas:

  • Se propaga a los hijos obligatorios. <table role="presentation"> anula también la semántica de sus filas y celdas; <ul role="none">, la de sus <li>. No afecta a otros descendientes: un enlace dentro de una celda sigue siendo un enlace.
  • El navegador lo ignora si el elemento es enfocable o tiene atributos ARIA globales (como aria-label o aria-describedby). En ese caso expone el rol implícito: un <button role="none"> sigue siendo un botón. Es una protección para que nada enfocable quede sin rol.

Error frecuente

<table role="presentation" class="tarifas">
  <tr><th>Abono</th><th>Precio</th><th>Validez</th></tr>
  <tr><td>Joven</td><td>20 €</td><td>30 días</td></tr>
</table>

Alguien añadió role="presentation" a la tabla de tarifas de una web de transporte «para que el lector no diga tantas cosas». El lector ya no anuncia filas, columnas ni encabezados: la persona oye «Abono Precio Validez Joven 20 € 30 días» y pierde la relación entre cada precio y su abono. Es un incumplimiento de 1.3.1 Información y relaciones. Las tablas de datos conservan siempre su semántica.

inert: dejar fuera de juego una zona entera

El atributo HTML global inert, disponible en todos los navegadores principales desde 2023, hace que el elemento y todo su contenido no puedan recibir el foco ni clics, y lo excluye del árbol de accesibilidad. Es la herramienta adecuada para el fondo de una ventana modal construida a mano, para un menú lateral cerrado que sigue en el DOM o para los pasos de un asistente que todavía no están activos.

<div id="pagina" inert>…cabecera, contenido, pie…</div>
<div role="dialog" aria-modal="true" aria-labelledby="titulo-aviso">
  <h2 id="titulo-aviso">Tu sesión va a caducar</h2>
  …
</div>
// Al abrir
document.getElementById('pagina').inert = true;
// Al cerrar: imprescindible restaurarlo
document.getElementById('pagina').inert = false;

Tres observaciones. El diálogo debe estar fuera del contenedor inerte, o también quedará inutilizable. Al cerrar hay que quitar el atributo, con el mismo riesgo de olvido que vimos con aria-hidden en la lección de errores. Y el contenido inerte se sigue viendo normal: si la persona lo ve pero no puede usarlo, indícalo visualmente (por ejemplo, oscureciendo el fondo). Si usas <dialog> con showModal(), el navegador vuelve inerte el resto de la página automáticamente; lo verás en el curso N3-C5.

disabled frente a aria-disabled

El atributo nativo disabled saca el control del orden de tabulación, impide los eventos de clic, excluye su valor del envío del formulario y lo expone como no disponible. Sus componentes inactivos quedan exentos de los requisitos de contraste de 1.4.3 Contraste (mínimo). El inconveniente: quien navega con teclado nunca llega a él, así que puede no descubrir que existe ni por qué no puede usarlo.

aria-disabled="true" solo cambia lo que se comunica: el control sigue siendo enfocable y el lector lo anuncia como no disponible, lo que permite explicar el motivo. A cambio, el bloqueo es responsabilidad tuya: ARIA no impide el clic ni el envío.

<button type="submit" aria-disabled="true" aria-describedby="motivo">
  Confirmar cita
</button>
<p id="motivo">Elige un día y una hora para continuar.</p>
boton.addEventListener('click', (evento) => {
  if (boton.getAttribute('aria-disabled') === 'true') {
    evento.preventDefault();
    anunciar('Elige un día y una hora para continuar.');
  }
});

Antes de deshabilitar, plantéate si hace falta. En muchos formularios es mejor dejar el botón de envío siempre activo y, al pulsarlo, indicar qué falta con mensajes de error claros (3.3.1 Identificación de errores). Para los campos cuyo valor puede leerse pero no cambiarse, el equivalente es readonly en los campos nativos o aria-readonly="true" en roles como textbox, gridcell o slider.

Punto clave

¿Debe desaparecer para todo el mundo? hidden. ¿Solo para el lector, porque es adorno o repetición? aria-hidden, nunca con enfocables. ¿Una zona entera fuera de uso temporalmente? inert. ¿Quitar la semántica a un elemento usado para maquetar? role="none". ¿Un control no disponible ahora? disabled, o aria-disabled si debe poder descubrirse y explicarse.

Pruébalo tú

En cualquier web, abre la consola de las herramientas de desarrollo y ejecuta:

document.querySelectorAll('[aria-hidden="true"] :is(a[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"]))')

Cada elemento que aparezca es un candidato a parada de foco muda (salvo que esté además deshabilitado o inerte). Pulsa Tab hasta llegar a alguno y comprueba con el Visor de voz de NVDA qué se anuncia.

Más información: aria-hidden en WAI-ARIA 1.2 y el atributo inert en MDN.

Resumen

  • Para cada mecanismo, comprueba tres cosas: si se ve, si está en el árbol de accesibilidad y si se puede enfocar y usar.
  • aria-hidden="true" oculta al lector sin tocar la pantalla ni el teclado: solo para adorno y repeticiones, nunca con enfocables, y no se deshace desde dentro.
  • role="none" quita el rol pero no el contenido, se propaga a los hijos obligatorios y se ignora en elementos enfocables o con atributos ARIA globales.
  • inert desactiva una zona entera (foco, clics y árbol) y hay que retirarlo al terminar.
  • disabled saca el control del recorrido del teclado; aria-disabled lo mantiene descubrible, pero obliga a bloquear la acción con JavaScript.

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.