development
¿Qué es ARIA? Roles, landmarks y regiones activas
ARIA permite a los desarrolladores hacer accesible el contenido web dinámico para los lectores de pantalla. Aprende cómo funcionan los roles, los landmarks y las regiones activas — y cuándo no usarlos.
Qué es ARIA, y qué no es
ARIA son las siglas de Accessible Rich Internet Applications (aplicaciones de internet enriquecidas accesibles). Es un conjunto de atributos definido por la Iniciativa de Accesibilidad Web (WAI) del W3C que permite a los desarrolladores comunicar el significado y el estado de los elementos de la interfaz a las tecnologías de asistencia, como los lectores de pantalla.
La regla más importante sobre ARIA es también la que más se ignora: no uses ARIA cuando el HTML nativo pueda hacer el trabajo. Un elemento <button> ya se anuncia como botón y responde a los eventos de teclado. Un elemento <nav> ya comunica un landmark de navegación a los lectores de pantalla. Añadir role="button" a un <div> y luego programar su comportamiento es más difícil de mantener, más fácil de romper y normalmente peor para la accesibilidad que usar el elemento adecuado desde el principio.
ARIA no:
- Hace que el contenido sea visible o interactivo: solo cambia lo que anuncia la tecnología de asistencia
- Arregla un acceso por teclado defectuoso: sigues necesitando
tabindexy escuchadores de eventos - Sustituye a un HTML semántico bien estructurado
Donde ARIA ayuda de verdad es cuando el HTML nativo no tiene ningún elemento para lo que estás construyendo: un selector de fechas, un banner de notificaciones en directo, un combobox personalizado, una vista de árbol. En esos casos, ARIA te permite comunicar la semántica que el HTML no puede.
Roles ARIA
Un rol indica a la tecnología de asistencia con qué tipo de elemento está tratando. Todo elemento interactivo tiene un rol implícito derivado de su etiqueta HTML. El elemento <a> tiene el rol link. El elemento <input type="checkbox"> tiene el rol checkbox. El elemento <h2> tiene el rol heading.
Cuando construyes un elemento personalizado que no tiene equivalente en HTML, le asignas un rol explícito:
<!-- Un interruptor personalizado construido a partir de un div -->
<div
role="switch"
aria-checked="false"
tabindex="0"
>
Modo oscuro
</div>
Ahora el lector de pantalla lo anunciará como un control de tipo interruptor y locutará su estado activado o desactivado. Sin el rol, se anunciaría como texto plano y el usuario no tendría ni idea de que es interactivo.
Roles habituales y cuándo usarlos
Los roles de widget describen controles interactivos:
| Rol | Úsalo cuando |
|---|---|
button | Un elemento personalizado en el que se puede hacer clic y para el que no hay una etiqueta HTML mejor |
checkbox | Una casilla personalizada de selección múltiple |
combobox | Un campo de texto combinado con un desplegable de tipo listbox |
dialog | Una capa modal (solo cuando no se usa el elemento nativo <dialog>) |
listbox | Una lista desplegable personalizada |
slider | Un control de rango personalizado |
switch | Un interruptor de encendido y apagado |
tab, tablist, tabpanel | Una interfaz de pestañas |
tooltip | Una descripción breve que se muestra al pasar el ratón o al recibir el foco |
Los roles de estructura del documento describen contenido no interactivo:
article— una pieza de contenido autónomafigure— una imagen con pielist,listitem— cuando se necesita semántica de lista en elementos que no son listaspresentation/none— elimina el rol implícito de un elemento (úsalo rara vez y con cuidado)
Un error crítico: añadir roles sin comportamiento
Cada rol conlleva un contrato que los lectores de pantalla y los usuarios de teclado esperan que se respete. Un role="button" debe responder tanto a Intro como a Espacio. Un role="checkbox" debe alternar su estado con Espacio. Un role="link" debe navegar con Intro.
Si añades el rol pero no el comportamiento correspondiente, estás induciendo activamente a error a los usuarios de tecnología de asistencia. Oyen que se anuncia un control, intentan interactuar con él usando el atajo de teclado esperado y no ocurre nada. Esto es peor que no poner ningún ARIA.
Landmarks de ARIA
Los landmarks son el esqueleto de navegación de la página. Permiten a los usuarios de lectores de pantalla saltar entre las regiones principales sin tener que leer todo lo que hay en medio: el equivalente al vistazo con el que un usuario con visión abarca la disposición de la página.
HTML5 introdujo elementos semánticos que se corresponden directamente con los roles de landmark. Úsalos y los landmarks te salen gratis:
| Elemento HTML | Rol de landmark | Finalidad |
|---|---|---|
<header> | banner | Cabecera global del sitio (solo cuando es la cabecera de nivel superior, no dentro de un <article>) |
<nav> | navigation | Un menú de navegación |
<main> | main | El contenido principal de la página |
<aside> | complementary | Contenido secundario relacionado con el contenido principal |
<footer> | contentinfo | Pie global del sitio |
<form> | form | Un formulario (solo cuando tiene un nombre accesible) |
<section> | region | Una sección con nombre (solo cuando tiene un nombre accesible mediante aria-label o aria-labelledby) |
No necesitas añadir role="main" a un elemento <main>: es redundante. Los roles de landmark de ARIA solo hacen falta cuando no puedes usar el elemento HTML semántico, por ejemplo en una base de código heredada que genera <div class="sidebar">:
<div class="sidebar" role="complementary" aria-label="Artículos relacionados">
<!-- contenido de la barra lateral -->
</div>
Etiquetar landmarks cuando hay más de uno
Cuando una página tiene varias instancias del mismo landmark —dos elementos <nav>, dos elementos <section> con role="region"—, cada una debe tener un nombre accesible único para que los usuarios puedan distinguirlas:
<nav aria-label="Navegación principal">...</nav>
<nav aria-label="Navegación del pie">...</nav>
Sin etiquetas, el lector de pantalla anuncia ambas simplemente como «navegación». Con etiquetas, los usuarios oyen «Navegación principal, landmark de navegación» y «Navegación del pie, landmark de navegación» y pueden elegir la correcta en la lista de landmarks.
Regiones activas de ARIA
Una región activa (live region) es una zona de la página cuyo contenido se actualiza de forma dinámica y cuyas actualizaciones deben anunciarse automáticamente a los usuarios de lectores de pantalla sin que tengan que mover el foco.
El atributo principal es aria-live. Admite tres valores:
off— las actualizaciones no se anuncian (el valor por defecto de todos los elementos)polite— las actualizaciones se anuncian cuando el usuario termina su tarea actualassertive— las actualizaciones interrumpen de inmediato lo que esté locutando el lector de pantalla
<!-- Un área de mensajes de estado que se rellena tras enviar un formulario -->
<div aria-live="polite" id="status-message"></div>
<script>
document.getElementById('status-message').textContent =
'Tu mensaje se ha enviado.';
</script>
Cuando cambia el contenido de texto, un lector de pantalla con aria-live="polite" espera una pausa en el habla y entonces anuncia el contenido nuevo. Usa polite para la inmensa mayoría de las actualizaciones dinámicas. Reserva assertive únicamente para fallos críticos —un error de pago, un aviso de expiración de sesión— en los que la información es lo bastante urgente como para justificar la interrupción del usuario.
Roles abreviados para las regiones activas
Dos roles agrupan la semántica de aria-live en un único atributo:
role="status"— equivale aaria-live="polite". Úsalo para mensajes de éxito, estados de carga y actualizaciones no urgentes.role="alert"— equivale aaria-live="assertive"e implica ademásaria-atomic="true". Úsalo para mensajes de error y fallos críticos.
<!-- Error anunciado de inmediato, interrumpiendo el habla en curso -->
<div role="alert" id="payment-error"></div>
<!-- Actualización de estado anunciada con cortesía tras el habla en curso -->
<div role="status" id="cart-count">3 artículos en el carrito</div>
Errores habituales con las regiones activas
Añadir contenido antes de que el elemento esté en el DOM. El navegador registra la región activa cuando el elemento se analiza por primera vez. Si insertas el elemento y estableces su contenido de texto a la vez, algunos lectores de pantalla se pierden el anuncio por completo. Incluye siempre el contenedor de la región activa en el HTML inicial y actualiza su contenido después mediante JavaScript.
Usar assertive para todo. Las regiones activas asertivas interrumpen lo que el usuario esté haciendo, incluidos otros anuncios. Un recuento de resultados de búsqueda que se actualiza mientras el usuario escribe no justifica un role="alert". Abusar de assertive produce una experiencia hostil para los usuarios de lectores de pantalla.
Actualizar la región activa con demasiada frecuencia. Si un indicador de progreso actualiza su región activa cada 100 milisegundos, la cola de habla se desborda y los usuarios no oyen nada útil. Actualiza el texto activo solo en hitos significativos —25 %, 50 %, 75 %, completado— o aplica un debounce a las actualizaciones con un temporizador.
Olvidar aria-atomic. Por defecto, solo se anuncia el nodo de texto que ha cambiado dentro de una región activa. Si quieres que se relea la región entera (y no solo el fragmento modificado), añade aria-atomic="true":
<div aria-live="polite" aria-atomic="true">
Quedan <span id="count">2</span> artículos
</div>
Sin aria-atomic, un lector de pantalla puede anunciar solo «2» cuando el recuento pasa de 3 a 2. Con él, se locuta la frase completa «Quedan 2 artículos», que es casi siempre lo que quieres.
Otros atributos ARIA esenciales
aria-label — proporciona un nombre accesible cuando no procede un texto visible:
<button aria-label="Cerrar diálogo">✕</button>
aria-labelledby — apunta a otro elemento cuyo texto sirve como nombre accesible. Es preferible a aria-label cuando el texto de la etiqueta ya está visible en la página:
<h2 id="billing-heading">Dirección de facturación</h2>
<form aria-labelledby="billing-heading">...</form>
aria-describedby — apunta a un texto complementario que describe un elemento más allá de su nombre:
<input type="password" aria-describedby="pwd-hint">
<p id="pwd-hint">Debe tener al menos 12 caracteres e incluir un símbolo.</p>
aria-expanded — indica si un elemento plegable (desplegable, acordeón, menú) está abierto o cerrado. Actualízalo en JavaScript cada vez que cambie el estado:
<button aria-expanded="false" aria-controls="nav-menu">Menú</button>
<ul id="nav-menu" hidden>...</ul>
aria-hidden="true" — elimina un elemento del árbol de accesibilidad. Úsalo para iconos decorativos, texto duplicado o elementos visuales que añadirían ruido para los usuarios de lectores de pantalla:
<span aria-hidden="true">★★★★☆</span>
<span class="sr-only">4 de 5 estrellas</span>
aria-disabled="true" — marca un control como deshabilitado sin sacarlo del orden de foco. Resulta útil cuando quieres que los usuarios descubran que el control existe y entiendan por qué no está disponible, en lugar de que se lo salten en silencio:
<button aria-disabled="true">Enviar (completa antes todos los campos)</button>
Probar ARIA en la práctica
Escribir atributos ARIA es sencillo. Acertar con ellos exige probarlos. Los escáneres automáticos detectan patrones claramente rotos: un role="button" sin nombre accesible, un aria-labelledby que referencia un ID inexistente, una región activa con un valor de aria-live no válido. Lo que no pueden decirte es si el texto anunciado tiene sentido en su contexto, ni si un widget personalizado complejo se comporta correctamente cuando se navega solo con el teclado.
Para pruebas en condiciones reales, combina al menos dos parejas de lector de pantalla y navegador:
- NVDA + Chrome en Windows — gratuito, muy extendido, próximo a la población real de usuarios de lectores de pantalla
- VoiceOver + Safari en macOS o iOS — integrado en el sistema, imprescindible para probar la accesibilidad móvil
- JAWS + Chrome o Edge en Windows — de pago, pero el lector de pantalla más utilizado en entornos corporativos
Navega por tus componentes interactivos usando solo el teclado. Escucha con atención lo que se anuncia cuando abres un menú, envías un formulario con un error de validación o disparas la actualización de una región activa. Si el anuncio es ambiguo o engañoso, la implementación de ARIA está mal, diga lo que diga cualquier herramienta automática.
La regla que lo abarca todo
La especificación de ARIA incluye cinco reglas de autoría. La primera es la más importante:
Si puedes usar un elemento o atributo HTML nativo que ya incorpore la semántica y el comportamiento que necesitas, en lugar de reutilizar un elemento y añadirle un rol, estado o propiedad de ARIA para hacerlo accesible, hazlo.
Construye con HTML semántico. Recurre a ARIA solo cuando el HTML se quede corto. Prueba con un lector de pantalla real. Eso cubre casi todas las situaciones con las que te vas a encontrar.
Para una comprobación práctica de cómo están implementados los atributos ARIA en todo tu sitio, nuestras auditorías manuales de accesibilidad incluyen pruebas con lectores de pantalla realizadas por personas que usan tecnología de asistencia a diario y que detectan problemas sutiles de ARIA que las herramientas automáticas pasan por alto.
Descubre cómo usa ARIA tu sitio con un escaneo gratuito