Icono del sitio IT&ライフハックブログ|学びと実践のためのアイデア集

La guía completa para el uso correcto de ARIA: Fundamentos de WAI-ARIA y anti-patrones para transmitir “lectura, operación y estado” (Cumplimiento práctico de WCAG 2.1 AA)

programming codes screengrab

Photo by Myburgh Roux on Pexels.com

La guía completa para el uso correcto de ARIA: Fundamentos de WAI-ARIA y anti-patrones para transmitir “lectura, operación y estado” (Cumplimiento práctico de WCAG 2.1 AA)

Resumen (puntos clave primero)

  • ARIA es poderosa, pero cuando se usa incorrectamente puede romper la accesibilidad. Es una “herramienta fuerte”. El mantra es «Primero lo nativo, ARIA solo donde sea necesario».
  • Lo más importante es transmitir correctamente Nombre, Rol y Estado/Valor a las tecnologías de asistencia.
  • No intentes resolver todo con aria-label. Mantén la coherencia con las etiquetas visibles y añade explicaciones con aria-describedby cuando sea necesario.
  • El camino más rápido es aprender los patrones seguros para interfaces compuestas comunes como modales, pestañas, menús, comboboxes y regiones en vivo.
  • Este artículo incluye muchos anti-patrones de ARIA que causan problemas con frecuencia en proyectos reales, junto con ejemplos de reemplazo listos para usar.

Público objetivo (concreto): Ingenieros front-end, diseñadores UI/UX, responsables de sistemas de diseño, ingenieros de QA, desarrolladores de CMS, especialistas en accesibilidad e implementadores de agencias
Nivel de accesibilidad: Orientado al cumplimiento de WCAG 2.1 AA (especialmente 4.1.2 Nombre, Rol, Valor; 2.1.1 Teclado; 1.3.1 Información y relaciones; 2.4.6 Encabezados y etiquetas, etc.)


1. Introducción: ARIA no es un “hechizo mágico”, sino un lenguaje para explicar

WAI-ARIA (ARIA) es un mecanismo para complementar el significado de la interfaz de usuario para tecnologías de asistencia como los lectores de pantalla.
Por ejemplo, un botón se entiende como “algo clicable” porque el elemento <button> tiene ese rol incorporado.

Sin embargo, en el trabajo del mundo real, a menudo encontramos botones construidos con div por libertad visual, o interfaces complejas como pestañas, menús, comboboxes y modales. En esas situaciones, ARIA puede ser extremadamente útil.

Dicho esto, ARIA no mejora automáticamente las cosas. Si declaras un rol o estado incorrecto, envías información errónea a las tecnologías de asistencia.
En este artículo organizaremos cuidadosamente la mentalidad y los patrones seguros necesarios para usar ARIA de forma correcta, mínima y sin romper nada.


2. La regla de oro absoluta: «Primero lo nativo, ARIA solo para lo que falta»

La regla férrea de ARIA puede expresarse con fuerza de la siguiente manera:

Usa ARIA solo para lo que no se puede hacer con HTML nativo

2.1 ¿Por qué “primero lo nativo”?

Los elementos nativos (button, a, input, select, etc.) ya incluyen:

  • Interacción por teclado
  • Gestión del foco
  • Roles integrados
  • Estados (deshabilitado, marcado, etc.)
  • Cálculo del nombre accesible

Estos se han optimizado durante años por los navegadores y las tecnologías de asistencia.
En contraste, div role="button" a menudo se convierte en un botón solo en apariencia, obligándote a implementar manualmente el manejo de Enter/Espacio, la posibilidad de recibir foco, el comportamiento de deshabilitado y más. El margen de error aumenta drásticamente.

2.2 Algunas cosas que ARIA no puede arreglar

ARIA no mejora por sí misma el diseño visual ni la calidad de la interacción:

  • Contraste de color insuficiente
  • Objetivos táctiles demasiado pequeños
  • Orden de tabulación roto
  • Lenguaje excesivamente complejo

Estas cosas no se pueden resolver con ARIA. Por eso el orden correcto es: arreglar primero la estructura y la interacción, y luego complementar el significado con ARIA.


3. Empieza aquí: acertar con Nombre, Rol y Estado/Valor (NRV)

La información más importante que ARIA proporciona a las tecnologías de asistencia es la comprensión básica de la interfaz, a menudo llamada NRV.

  • Nombre: ¿Cómo se llama? (p. ej., Buscar, Cerrar, Guardar)
  • Rol: ¿Qué es? (botón, enlace, pestaña, casilla de verificación…)
  • Estado/Valor: ¿Cuál es su estado actual? (abierto/cerrado, seleccionado, porcentaje de valor…)

3.1 Nombres accesibles: prioriza las etiquetas visibles

Siempre que sea posible, crea los nombres en este orden:

  1. Texto dentro del botón (lo más natural)
  2. <label> con for (formularios)
  3. aria-labelledby (para combinar varios elementos)
  4. aria-label (último recurso)

Ejemplo: usar un encabezado como parte del nombre de un botón (aria-labelledby)

<h2 id="dlgTitle">Notification Settings</h2>
<button aria-labelledby="dlgTitle openBtn" id="openBtn">
  Open
</button>

Esto produce una lectura más contextual, como “Notification Settings Open”.

3.2 Usa aria-describedby para explicaciones (no las mezcles en el nombre)

Mantén los nombres cortos y las explicaciones separadas. Esto reduce la fatiga auditiva.

<label for="email">Email address (required)</label>
<input id="email" type="email" aria-describedby="emailHint">
<p id="emailHint">Example: example@example.com</p>

4. Anti-patrones de ARIA: errores comunes y reemplazos seguros

Esta sección es crítica, así que seremos estrictos.

4.1 Uso excesivo de div role="button"

Problema: No es enfocable con Tab, no es operable con Espacio, estados deshabilitados falsos y muchos otros problemas.
Reemplazo: Simplemente usa <button>.

Malo:

<div role="button">Save</div>

Bueno:

<button type="button">Save</button>

4.2 Resolver todo con aria-label

Problema: Si las etiquetas visibles y las habladas no coinciden, los usuarios se confunden (WCAG 2.5.3 Etiqueta en el nombre).
Reemplazo: Empieza con texto visible y usa aria-label solo cuando sea inevitable.

4.3 Uso excesivo de aria-hidden="true" para “ocultar” cosas

Problema: Crea situaciones peligrosas donde el contenido es visible pero silencioso para los lectores de pantalla.
Reemplazo:

  • Si está oculto visualmente: usa hidden o display: none
  • Si se deshabilita la interacción del fondo en modales: usa inert donde esté soportado

4.4 Roles innecesarios (p. ej., role="button" en un <button>)

Problema: Redundante y a veces altera el comportamiento.
Reemplazo: Confía en la semántica nativa.
(Esto refleja el principio: ningún ARIA es mejor que un ARIA incorrecto).


5. Componente por componente: patrones ARIA seguros para la práctica

Esta es la sección central. Aprende estos patrones comunes de interfaz como “formas” estables.


5.1 Botones con iconos (Buscar, Cerrar, Compartir)

Punto clave: Trata el icono como decorativo (alt="") y nombra el botón en sí.

<button type="button" aria-label="Close">
  <img src="close.svg" alt="">
</button>
  • Los estilos de foco visibles (:focus-visible) también son obligatorios.

5.2 Divulgación (acordeones, detalles)

Punto clave: Usa button como disparador, aria-expanded para el estado y aria-controls para el objetivo.

<button aria-expanded="false" aria-controls="faq1" id="btn1">
  Can I change the delivery date?
</button>
<div id="faq1" hidden>
  Yes, you can change it before shipment.
</div>
  • Al abrirse, elimina hidden y establece aria-expanded="true".
  • Combinarlo con una estructura de encabezados (p. ej., h3) reduce la confusión.

5.3 Modales (diálogos)

Comportamientos obligatorios:

  • Mover el foco al modal al abrirlo
  • Atrapar el foco dentro
  • Cerrar con Esc
  • Restaurar el foco al disparador al cerrar
  • Asociar el título (aria-labelledby)

Ejemplo (patrón básico)

<button id="open">Open settings</button>

<div role="dialog" aria-modal="true" aria-labelledby="dlgTitle" hidden id="dlg">
  <h2 id="dlgTitle">Notification Settings</h2>
  <p id="dlgDesc">Select notification types and save.</p>

  <label><input type="checkbox"> Email notifications</label>
  <label><input type="checkbox"> Push notifications</label>

  <div class="actions">
    <button type="button" id="save">Save</button>
    <button type="button" id="close">Close</button>
  </div>
</div>

Nota: Si quieres silenciar completamente el fondo, inert es una opción segura donde esté soportada.
Los modales son muy propensos a errores, por lo que estandarizarlos en un sistema de diseño es extremadamente valioso.


5.4 Pestañas

Conceptos básicos:

  • role="tablist"
  • Las pestañas usan role="tab" (normalmente botones)
  • Los paneles usan role="tabpanel"
  • Selección mediante aria-selected
  • Navegación con flechas (tabindex rotativo)
<div role="tablist" aria-label="Product Information">
  <button role="tab" id="t1" aria-controls="p1" aria-selected="true" tabindex="0">Overview</button>
  <button role="tab" id="t2" aria-controls="p2" aria-selected="false" tabindex="-1">Specs</button>
  <button role="tab" id="t3" aria-controls="p3" aria-selected="false" tabindex="-1">Reviews</button>
</div>

<section role="tabpanel" id="p1" aria-labelledby="t1">…</section>
<section role="tabpanel" id="p2" aria-labelledby="t2" hidden>…</section>
<section role="tabpanel" id="p3" aria-labelledby="t3" hidden>…</section>

Nota: Las pestañas sirven para cambiar vistas dentro del mismo contexto. Si parece navegación entre páginas, normalmente los enlaces son más apropiados.


5.5 Regiones en vivo (notificaciones: guardado completo, resultados de búsqueda)

Punto clave: Transmite los resultados de forma discreta. Usa role="status" para éxitos y role="alert" para errores.

<div id="status" role="status" aria-atomic="true"></div>

<script>
  function saved(){
    document.getElementById('status').textContent = 'Saved successfully.';
  }
</script>
  • aria-atomic="true" es útil cuando quieres que se lea la frase completa.

5.6 Comboboxes (sugerencias de búsqueda, autocompletado)

Esta es un área difícil. El coste de implementación es alto y el mal uso de ARIA es común. Siempre que sea posible, usa bibliotecas de UI maduras o elementos nativos como datalist en lugar de crear uno desde cero.

Si debes construir uno, gestiona correctamente role="combobox", aria-expanded, aria-controls, aria-activedescendant, la navegación con flechas y los anuncios.
(Este tema por sí solo podría llenar un artículo entero, por lo que fijar un único patrón aprobado en tu sistema de diseño suele ser el enfoque práctico).


6. Texto, etiquetas y diseño de estados: no confundas a los usuarios con palabras

Ni siquiera un ARIA perfecto ayudará si las etiquetas son vagas. Palabras como “Aquí”, “Detalles” o “Enviar” pierden significado en listas de enlaces o botones.

6.1 Las etiquetas fuertes usan “verbo + objeto”

  • Malo: Detalles
  • Bueno: Ver detalles del pedido, Cambiar dirección de envío, Descargar recibo

6.2 Duplica el estado visual y auditivamente

  • Estado expandido: aria-expanded + texto “Abrir/Cerrar”
  • Estado de selección: aria-selected + resaltado visual
  • Errores: aria-invalid + texto de error

7. Pruebas: juzga ARIA por “¿funciona?”, no por “¿está ahí?”

ARIA es declarativo. La única validación fiable es la interacción real y la salida de lectura.

7.1 Prueba rápida de cinco minutos (enfocada en ARIA)

  1. ¿Se pueden completar todas las acciones principales con Tab?
  2. ¿Los nombres de botones/enlaces son específicos cuando se listan?
  3. ¿aria-expanded refleja correctamente el estado abierto/cerrado?
  4. En los modales, ¿el foco permanece dentro y vuelve al cerrar?
  5. ¿aria-invalid y aria-describedby se aplican correctamente a los errores?
  6. ¿Se anuncian los mensajes de estado/alerta cuando es necesario?

7.2 Comprobaciones mínimas con lector de pantalla

  • Los roles como “botón” o “casilla de verificación” son correctos
  • Los estados como “seleccionado” o “expandido” se anuncian
  • Las etiquetas describen el propósito, no los nombres de los iconos

8. Integrarlo en un sistema de diseño: hacer de ARIA un estándar del equipo

Para conectarlo con un sistema de diseño, ARIA debe integrarse de la siguiente manera.

8.1 Documentar el “conjunto mínimo de ARIA” por componente

Ejemplo para divulgación:

  • Requerido: aria-expanded, aria-controls
  • Comportamiento: debe reflejar el estado abierto/cerrado
  • Prohibido: div role="button"

8.2 Fijar un solo patrón de implementación

Permitir múltiples patrones conduce al infierno de las revisiones.
Decide “Las pestañas usan este patrón”, “Los modales usan este patrón” y comparte el código.

8.3 Definir criterios de aceptación por resultados

En lugar de “tiene un tablist”, exige:

  • “Las pestañas se pueden mover con las flechas y el estado seleccionado se anuncia”.

9. Valor para cada audiencia

  • Usuarios de lectores de pantalla: Nombres y estados correctos reducen drásticamente la desorientación.
  • Usuarios de teclado: El diseño nativo primero garantiza una operación natural.
  • Usuarios con diferencias cognitivas: Los cambios claros de estado evitan la confusión.
  • Equipos de desarrollo: Menos anti-patrones significan menos regresiones y revisiones más baratas.
  • Operaciones de sistemas de diseño: Los requisitos ARIA especificados garantizan una calidad consistente entre productos.

10. Evaluación del nivel de accesibilidad (objetivo de este artículo)

  • Soporte central para WCAG 2.1 AA
    • 4.1.2 Nombre, Rol, Valor: ARIA correcta y estados expuestos
    • 2.1.1 Teclado: Elementos nativos, reglas de interacción de modales/pestañas
    • 1.3.1 Información y relaciones: Estructura adecuada (pestañas/formularios)
    • 2.4.6 Encabezados y etiquetas: Etiquetas específicas y alineadas
    • 2.4.7 Foco visible: Asegurado mediante CSS y sistemas de diseño
    • 3.3.x Asistencia en la entrada: Asociación de errores (aria-invalid, aria-describedby)

En resumen, este artículo busca estabilizar las áreas más frágiles de la interfaz en el cumplimiento AA mediante el uso correcto de ARIA.


11. Conclusión: ARIA es más fuerte cuando es mínima y precisa

  1. Empieza con HTML nativo. Usa ARIA solo donde sea necesario.
  2. Arregla el NRV (Nombre, Rol, Estado/Valor) para estabilizar la experiencia con lectores de pantalla.
  3. Evita depender en exceso de aria-label; combina etiquetas visibles con aria-describedby.
  4. Estandariza patrones seguros para modales, pestañas, divulgaciones y notificaciones.
  5. Evita anti-patrones (botones con div, abuso de aria-hidden, roles innecesarios).
  6. Incorpora las especificaciones y criterios de aceptación en tu sistema de diseño.

ARIA es una herramienta para expresar amabilidad a través de un lenguaje preciso.
Mínima, precisa y sostenible. Que tu interfaz se convierta en un lugar donde nadie se pierda. Estaré encantado de apoyarte en cada paso del camino.


Referencias (fuentes principales)

Salir de la versión móvil