Saltar al contenido principal
Niquelao Accesibilidad web y desarrollo front-end en español: estándares WCAG, widgets accesibles y extensiones para Firefox, explicados con código real.

Algunos enlaces de este sitio son de afiliados: si compras a través de ellos, es posible que recibamos una comisión sin coste adicional para ti. Esto nunca afecta a nuestras recomendaciones. Consulta nuestra declaración de afiliados para más detalles. Divulgación de afiliados.

Roles y atributos de ARIA: mejores opciones comparadas

Los roles y atributos ARIA de la especificación WAI-ARIA 1.2 de la W3C superan el centenar, aunque un puñado resuelve la mayoría de los problemas de accesibilidad en widgets XHTML y CSS. Un rol define qué es un elemento y un atributo su estado o relaciones, pero ARIA no modifica el comportamiento del navegador: cada rol agregado exige implementar interacción con JavaScript.

Accessible Rich Internet Applications (ARIA) es una especificación del W3C que agrega semántica a elementos HTML que no la tienen en forma nativa. Un rol describe qué es un elemento (un button, una tab, un dialog), mientras que un atributo describe su estado o sus relaciones (aria-expanded, aria-controls, aria-labelledby). La primera regla de ARIA, publicada por el W3C en Usar ARIA, es contundente: si hay un elemento HTML nativo que ya hace el trabajo, úselo y no agregue ARIA.

La razón es que ARIA no modifica el comportamiento del navegador. Un <div role="button"> no recibe el foco con Tab, no responde a la tecla Intro o al espacio y no se envía con un formulario.

Sólo cambia lo que anuncia la tecnología de asistencia. Toda interacción debe implementarse con JavaScript y gestionarse con cuidado. En proyectos XHTML/CSS donde el HTML es estático y el JS es mínimo, esto significa que cada uno de los roles y atributos de aria que se agrega es una promesa que su código debe cumplir.

La segunda regla de ARIA pide no cambiar la semántica nativa a menos que sea imprescindible. Un <h2 role="tab"> rompe la estructura de los títulos y confunde a los lectores de pantalla que navegan por regiones. La tercera regla requiere que todos los controles ARIA puedan operarse con un teclado. La cuarta pide no utilizar aria-hidden="true" en elementos que reciben foco. La quinta, y el más olvidado, nos recuerda que cualquier elemento interactivo requiere un nombre accesible: un rol sin etiqueta es un botón mudo.

Cómo elegir: criterios antes de la lista

Elegir un rol o atributo no es cuestión de gustos. Estos criterios, aplicados en orden, evitan la mayoría de errores relacionados con los roles y atributos de aria:

Relacionado: — con plan gratuito para empezar hoy mismo.

  1. ¿Existe un elemento HTML nativo? Si es así, úselo. <button>, <details>, <dialog>, <input type="checkbox"> cubren más casos de los que la gente piensa.
  2. ¿El widget necesita estados dinámicos? Si cambia entre abierto/cerrado, seleccionado/no seleccionado o expandido/contraído, necesita atributos de estado (aria-expanded, aria-selected, aria-pressed).
  3. ¿Necesita relaciones entre elementos? Los atributos de relación (aria-controls, aria-labelledby, aria-describedby, aria-owns) conectan piezas que el árbol de accesibilidad no puede inferir del DOM.
  4. ¿Necesita anuncios en vivo? Las regiones en vivo (aria-live, role="status", role="alert") resuelven las actualizaciones sin mover el foco.
  5. ¿Puedo mantenerlo? Un patrón ARIA complejo sin pruebas de teclado o lector de pantalla es peor que no tener nada.

El coste de mantenimiento es el criterio más ignorado. Un role="tablist" bien hecho requiere administración de teclas de flecha, rotación de tabindex, sincronización de aria-selected y aria-controls y ocultación correcta de paneles inactivos. Si el equipo no puede manejar eso, un conjunto de enlaces con anclajes es más accesible y económico.

Comparativa de los roles ARIA más útiles

La tabla siguiente resume los roles que aparecen una y otra vez en auditorías reales, con su equivalente nativo cuando existe y la trampa más habitual.

RolPara qué sirveAlternativa nativaTrampa frecuente
buttonControl que ejecuta una acción<button>No añadir manejo de Enter/Espacio ni tabindex="0"
linkNavegación a otra URL<a href>Usarlo para acciones que no navegan
dialogVentana modal o no modal<dialog>No atrapar el foco ni devolverlo al cerrar
tablist / tab / tabpanelInterfaz de pestañasNinguna directaNo sincronizar aria-selected con el panel visible
menu / menuitemMenú de aplicación<select> o lista de enlacesUsarlo para menús de navegación web
alertMensaje urgente e inmediatorole="status" para lo no urgenteAbusar de él y saturar al lector de pantalla
statusActualización informativa<output>No insertarlo en el DOM antes de actualizar
progressbarProgreso de una tarea<progress>No actualizar aria-valuenow
tooltipDescripción emergentetitle (limitado)No asociarlo con aria-describedby
comboboxCampo con lista de sugerencias<datalist> (limitado)No anunciar el número de resultados

La elección entre role="alert" y role="status" es un buen ejemplo de una decisión con matices con respecto a los roles y atributos de aria. alerta interrumpe la lectura actual del lector de pantalla; status espera a que el usuario termine. Para un error de validación de formulario, “alerta” es apropiado. Para “3 resultados encontrados” mientras el usuario escribe, “estado” es correcto y “alerta” resulta intrusivo.

Vale la pena echarle un vistazo: — Accesibilidad gestionada: automatización combinada con revisión humana.

Atributos ARIA imprescindibles y cómo se combinan

Los atributos están asociados a cuatro familias y cada una resuelve un problema distinto.

Etiquetado. aria-label proporciona un nombre cuando no hay texto visible. aria-labelledby hace referencia al id de otro elemento y es preferible cuando el texto ya existe en la pantalla, porque mantiene una única fuente de verdad. aria-describedby agrega una descripción más larga, como el texto de ayuda de un campo. La diferencia importa: el nombre es lo que el usuario escucha al enfocar; la descripción es un contexto adicional que puede interrumpirse.

Estados. aria-expanded (verdadero/falso) para acordeones y menús desplegables. aria-selected para pestañas y opciones. aria-checked para casillas de verificación personalizadas, con el valor mixed para estados de tres estados. aria-pressed para alternar botones. aria-disabled cuando el elemento todavía es enfocable pero no operable, a diferencia del atributo nativo disabled, que lo elimina del orden de tabulación.

Relaciones. aria-controls indica qué elemento controla un botón. aria-ows reorganiza el árbol de accesibilidad cuando el DOM no refleja la relación visual. aria-activededescendiente le permite mantener el foco en un contenedor mientras anuncia el elemento activo, un patrón común en los cuadros combinados.

Regiones en vivo. aria-live="polite" o "asertivo" definen urgencia. aria-atomic="true" hace que se anuncie todo el bloque en lugar de solo la parte modificada. aria-relevant filtra qué cambios se anuncian.

Un detalle que muchas veces se pasa por alto: los atributos ARIA sólo funcionan en elementos con un rol válido. aria-expanded en un <div> sin una función no se anunciará. Y los valores booleanos ARIA son cadenas de texto (“true”, ”false”), no valores booleanos de JavaScript; escribir aria-expanded=“false”` como una propiedad booleana producirá resultados inconsistentes.

Relacionado: — La que acredita tu experiencia en accesibilidad..

Errores que arruinan la accesibilidad de un widget

El error más costoso es usar ARIA para arreglar un HTML mal estructurado. Agregue role="navigation" a un <div> cuando ya había un <nav> disponible duplicando regiones y confunde la navegación con puntos de referencia.

El segundo error es el enfoque. Un widget modal que no mueve el foco cuando se abre, no lo atrapa mientras está abierto y no lo devuelve al disparador al cerrarlo, deja al usuario del teclado navegando a través de contenido invisible. El elemento nativo <dialog> resuelve parte de esto, pero no todo: devolver el foco sigue siendo responsabilidad del desarrollador.

El tercer error es ocultar con aria-hidden elementos que siguen siendo enfocables. Un menú cerrado con aria-hidden="true" pero sin display: none o visibility: hide mantiene sus enlaces en el orden de tabulación, y el usuario enfoca elementos que no puede ver. La combinación correcta es ocultar visualmente y del árbol de accesibilidad a la vez.

Si estás de compras: — Superposición de IA que promete cumplimiento WCAG en 48 horas.

El cuarto error es el nombre accesible ausente. Un <button> con un solo icono SVG requiere una aria-label o un <span class="visually-hidden"> con texto. Un SVG decorativo requiere aria-hidden="true" y focusable="false" por lo que Internet Explorer y algunos navegadores más antiguos no lo incluyen en el orden de tabulación.

Herramientas para probar roles y atributos ARIA

No existe ninguna herramienta que reemplace las pruebas con un lector de pantalla real, pero la combinación de varias herramientas detecta la mayoría de las fallas en las funciones y atributos de aria.

Validación estática. El validador ARIA W3C (parte de Nu HTML Checker) detecta roles inexistentes, atributos mal escritos y combinaciones prohibidas. ax DevTools y Lighthouse señalan roles sin nombres accesibles y sin atributos obligatorios.

Inspección del árbol de accesibilidad. Chrome y Firefox DevTools le permiten ver el árbol de accesibilidad exactamente como lo recibe la tecnología de asistencia. Es la forma más rápida de comprobar si realmente se aplicó un rol y qué nombre accesible calculó el navegador.

Prueba manual. Navega por todo el widget solo con el teclado (Tab, Shift+Tab, flechas, Enter, Espacio, Escape) y luego con NVDA en Windows, JAWS si está disponible o VoiceOver en macOS e iOS. La combinación de un lector de sobremesa y uno móvil cubre la mayoría de casos reales.

Documentación de referencia. La Guía de prácticas de creación de ARIA (APG) del W3C incluye patrones completos con ejemplos de teclado y código. Esta es la fuente que se debe consultar antes de inventar un nuevo patrón.

Cómo decidir en un proyecto XHTML/CSS real

En sitios XHTML con CSS y JavaScript livianos, la estrategia más rentable es comenzar con HTML nativo y agregar ARIA solo donde el nativo no llega. Un formulario con <label>, <fieldset> y <legend> correctos requiere muy poca ARIA. Una tabla de datos con <ésimo alcance> tampoco lo hace. Los roles ARIA entran en juego cuando aparecen patrones que HTML no cubre: pestañas, acordeones, cuadros combinados con filtrado, diálogos modales y notificaciones dinámicas.

Es recomendable documentar cada uso de los roles y atributos de ARIA en el propio código con un comentario que explique por qué está ahí. Cuando alguien refactorice el componente seis meses después, sabrá si los “aria-controls” todavía son necesarios o se han quedado huérfanos. Los atributos ARIA huérfanos, que apuntan a “id” que ya no existen, son una fuente silenciosa de fallas que ningún validador detecta de manera confiable.

Finalmente, trate la accesibilidad como parte de la definición de “hecho” del componente, no como una auditoría posterior. Un widget con funciones ARIA probado con el teclado y el lector de pantalla desde la primera confirmación cuesta mucho menos que uno reparado después de la auditoría.

Conclusiones clave

  • Los roles y atributos de ARIA no añaden comportamiento: un rol sin teclado y gestión de enfoque es peor que no tener nada.
  • La primera regla de ARIA es utilizar HTML nativo siempre que exista; <botón>, <diálogo> y <detalles> cubren más casos de los que uno podría pensar.
  • Los atributos se agrupan en etiquetas, estados, relaciones y regiones activas; cada familia resuelve un problema diferente.
  • role="alert" interrumpe y role="status" espera: elegir incorrectamente satura al usuario del lector de pantalla.
  • Los valores booleanos ARIA son cadenas (“true”/”false”`), y los atributos solo funcionan en elementos con una función válida.
  • Es obligatoria la prueba con un teclado y un lector de pantalla real; Los validadores solo detectan una parte de las fallas.

Fuentes y lecturas adicionales

  • WAI-ARIA — Wikipedia: Iniciativa de Accesibilidad Web – Aplicaciones Ricas de Internet Accesibles (WAI-ARIA) es una especificación técnica publicada por el Consorcio World Wide Web (W3C) que…

Preguntas frecuentes

¿Cuál es la diferencia entre un rol y un atributo ARIA?

Un rol define qué es un elemento para la tecnología de asistencia, como role="tab" o role="dialog". Un atributo describe su estado o sus relaciones, como “aria-expanded” o “aria-labelledby”. Los roles se aplican al elemento que representa el componente; Los atributos generalmente se aplican al mismo elemento o aquellos que están relacionados con él.

¿Cuándo debo usar ARIA en lugar de HTML nativo?

Sólo cuando no hay ningún elemento HTML que cubra el patrón. La primera regla de W3C ARIA es explícita: si hay un elemento nativo, úselo. Los roles ARIA son necesarios para pestañas, acordeones, cuadros combinados con filtrado y diálogos modales, entre otros patrones que HTML no puede implementar por sí solo.

¿Qué significa que un elemento tiene un nombre accesible?

Un nombre accesible es el texto que anuncia el lector de pantalla al enfocar el elemento. Se calcula a partir del contenido, de aria-label, de aria-labelledby o de un <label> asociado, en un orden de prioridad definido por la especificación. Un rol interactivo sin un nombre accesible es un control que el usuario no puede identificar.

¿Por qué mi role="button" no responde al teclado?

Porque ARIA no agrega comportamiento. Un <div role="button"> necesita tabindex="0" para recibir el foco y manejadores de keydown para Enter y Space. La solución más simple y sólida es utilizar el elemento nativo <button>, que ya incluye el foco, activación de teclado y envío de formulario.

¿Es malo usar aria-hidden="true"?

Es correcto ocultar contenido decorativo o duplicado del árbol de accesibilidad, pero nunca debe aplicarse a elementos que reciben foco. Si un elemento enfocable se deja con aria-hidden="true", el usuario del teclado puede enfocar algo que el lector de pantalla no anuncia. Combínelo siempre con ocultamiento visual real.

¿Qué herramientas validan los roles y atributos ARIA?

El W3C Nu HTML Checker incluye validación de roles y atributos de ARIA y detecta roles inexistentes o combinaciones prohibidas. axe DevTools y Lighthouse señalan roles sin un nombre accesible y sin atributos obligatorios. Para verificar el resultado final, el inspector del árbol de accesibilidad en el navegador DevTools muestra exactamente lo que recibe la tecnología de asistencia.


¿Cumplir WCAG sin tocar el código?

Superposición de IA que promete cumplimiento WCAG en 48 horas