ARIA
Accessible Rich Internet Applications — semántica accesible para interfaces web
Conjunto de atributos HTML que describen roles, estados y propiedades de un componente para las tecnologías de apoyo. La primera regla de su especificación es no usarlo si existe un elemento HTML nativo que ya haga el trabajo.
Qué es ARIA
ARIA —Accessible Rich Internet Applications— es un conjunto de atributos que se añaden al HTML para describir qué es un elemento, en qué estado está y qué relación tiene con otros. Su público no son los ojos: es el árbol de accesibilidad, la representación de la página que consumen las tecnologías de apoyo.
El problema que resuelve es concreto. HTML tiene elementos para lo clásico:
botones, enlaces, campos de formulario, tablas, listas. No tiene elementos para
un carrusel, un árbol desplegable, un panel de pestañas o un combo de
autocompletado. Cuando construyes uno de esos, el navegador ve un montón de
div y span sin significado, y eso es exactamente lo que anuncia. ARIA
permite decirle: esto es una pestaña, este panel le corresponde, esta está
seleccionada.
Los atributos se agrupan en tres familias:
- Roles — qué es la cosa:
role="dialog",role="tab",role="alert". - Estados — qué le pasa ahora y puede cambiar:
aria-expanded,aria-checked,aria-disabled,aria-invalid. - Propiedades — características más estables:
aria-label,aria-labelledby,aria-describedby,aria-controls.
La primera regla: no usar ARIA
La especificación del W3C empieza con una advertencia que conviene tatuarse:
si existe un elemento HTML nativo que ya hace el trabajo, úsalo y no pongas
ARIA. Un <button> es preferible a un <div role="button"> en todos los
casos sin excepción.
La razón es que ARIA solo cambia lo que se anuncia, no lo que se puede
hacer. No añade comportamiento. Un div con role="button" sigue sin ser
alcanzable con el tabulador, sigue sin activarse con Enter ni con la barra
espaciadora, y sigue sin comportarse como un botón en el formulario. Para
igualar a un <button> real hay que añadirle tabindex, gestores de teclado
para dos teclas distintas, estilos de foco y el estado deshabilitado a mano. Y
todo eso hay que mantenerlo.
De ahí sale la frase que repito en cada revisión de código: ARIA mal puesto es peor que no poner nada. Sin ARIA, un elemento raro se anuncia como texto y la persona al menos percibe que hay algo ahí. Con un rol mentiroso, se anuncia como un botón que no funciona, y eso no es una limitación: es una trampa.
Los cuatro usos que sí valen la pena
Después de descartar todo lo que HTML ya resuelve, queda un núcleo de casos donde ARIA es imprescindible.
Nombrar lo que no tiene texto visible. Un botón que solo contiene un icono
necesita aria-label. Dos navegaciones en la misma página se distinguen con
aria-label="principal" y aria-label="pie". Si hay texto visible que ya
sirve de nombre, aria-labelledby es mejor que repetirlo.
Comunicar estados que cambian. Un desplegable necesita aria-expanded que
pase de false a true al abrirse. Es de los atributos más útiles y de los que
más veces encuentro puestos como valor fijo en el HTML, sin que ningún
JavaScript los actualice nunca.
Anunciar lo que ocurre sin recargar la página. Los avisos de «producto
añadido», «formulario enviado» o «tres resultados encontrados» solo llegan a
quien no ve la pantalla si están dentro de una región con aria-live, o en un
contenedor con role="alert" para lo urgente.
Describir relaciones. aria-describedby conecta un campo con su texto de
ayuda o con su mensaje de error, de forma que se anuncian juntos al llegar al
campo.
Lo que veo cuando reviso código
Cuando abro el inspector de una web con problemas, ARIA me da una lectura rápida de cómo se ha trabajado. Y hay un contraste que se repite: las webs con más atributos ARIA suelen ser las más inaccesibles. No es casualidad. La proliferación de atributos es lo que ocurre cuando alguien intenta parchear un marcado que no se apoya en HTML semántico.
El caso que más veces he desmontado es el menú de navegación. Alguien montó los
enlaces con div, luego añadió role="menu" y role="menuitem" porque suena a
menú, y con eso convirtió una navegación normal en un widget de aplicación que
un lector de pantalla anuncia con reglas de teclado que nadie ha implementado.
Ese ARIA se arregla borrándolo: una lista de enlaces dentro de un <nav> es más
accesible y menos código.
El segundo caso es el modal. role="dialog" y aria-modal="true" puestos, y
detrás nada: el foco no entra al abrirse, se puede tabular fuera hacia la página
que está debajo, Escape no cierra y al cerrar el foco no vuelve al botón que lo
abrió. Los atributos anuncian un diálogo; el comportamiento es el de una capa
flotante cualquiera.
Al maquetar este sitio la regla fue la contraria: usar HTML nativo hasta que deja de dar, y solo entonces añadir el atributo mínimo. La evidencia de lo que se ha comprobado está en la declaración de accesibilidad.
Por qué le importa a un negocio
Porque es donde se rompe la compra. Los componentes que llevan ARIA son precisamente los interactivos: filtros, selectores, carritos, formularios de varios pasos. Si fallan, no pierdes matices de experiencia: pierdes la transacción entera.
Porque las herramientas automáticas no lo cubren bien. Un validador detecta
un rol mal escrito o un aria-labelledby que apunta a un identificador
inexistente. No detecta que el rol es mentira, ni que el estado no se actualiza,
ni que el nombre accesible no describe lo que hace el botón. Esa parte hay que
probarla con el teclado y con el árbol de accesibilidad delante.
Porque el HTML semántico que sustituye a ARIA es el mismo que ayuda al
posicionamiento. Un rastreador tampoco ve el diseño: lee estructura. Cambiar
div por elementos con significado mejora las dos cosas a la vez, algo que
desarrollo en la sección de SEO.
Errores frecuentes
role="button" sobre un div. Es el error insignia. Anuncia un botón que
no se puede alcanzar con el tabulador ni activar con el teclado. La solución no
es añadir más atributos: es usar <button>.
Poner aria-expanded y no actualizarlo. Si el valor está escrito fijo en el
HTML y el JavaScript solo cambia una clase CSS, el estado anunciado es siempre
el mismo. La persona oye «contraído» con el menú abierto delante.
Duplicar el nombre accesible. Un aria-label sobre un elemento que ya
tiene texto visible sustituye a ese texto. Si no coinciden, quien usa control
por voz dice en alto lo que lee y no pasa nada, porque el nombre real es otro.
Usar aria-hidden para ocultar cosas visibles. aria-hidden="true" no
oculta a la vista: oculta al árbol de accesibilidad. Puesto sobre contenido que
se ve, crea elementos que existen para unos usuarios y no para otros. Y si
dentro hay algo enfocable, se llega a ello con el tabulador sin que se anuncie
nada.
Copiar un patrón del APG a medias. Las guías de autoría del W3C describen roles, estados y el comportamiento de teclado que los acompaña. Coger los atributos y dejar el teclado fuera produce justo el componente mentiroso que más daño hace.
Términos relacionados
- HTML HyperText Markup Language — lenguaje de marcado de la web
- WCAG Web Content Accessibility Guidelines — Pautas de Accesibilidad para el Contenido Web
- lector de pantalla programa que lee la pantalla en voz alta
- tecnología de apoyo herramientas que permiten usar la web con una discapacidad
- foco visible ver siempre dónde estás al navegar con el teclado
- texto alternativo la descripción escrita de una imagen