Medir Usabilidad Web

Menú

ACCESIBILIDAD EN LA PRÁCTICA

WAI-ARIA: comprueba lo que anuncia

Relaciona el nombre, el estado y el comportamiento real de un componente.

Dos desarrolladores señalan y revisan código en la pantalla de un portátil.

Pruébalo en tu web

01

Elige HTML adecuado

Para una acción utiliza un botón. Para navegar, un enlace con destino.

02

Comprueba el estado

Abre y cierra un desplegable. El estado expandido debe coincidir con lo visible y actualizarse.

03

Prueba la interacción

Revisa teclado, foco y árbol de accesibilidad; contrasta con un lector de pantalla en el entorno de prueba.

CASO SIMULADO

Un botón que anuncia «contraído» mientras el contenido está abierto transmite un estado incorrecto. Cambiar solo el atributo tampoco abre el contenido.

El foco se ve en el botón que abre el diálogo y regresa a ese botón al cerrarlo.
Prueba también el recorrido de teclado: apertura, interacción, cierre y regreso.

Qué hacer con el resultado

Si HTML ya resuelve la necesidad, úsalo. Añade ARIA cuando falte información y comprueba que la implementación sostiene lo que comunica.

Para profundizar

Abrir la guía completa, el código y las fuentes

ARIA permite comunicar semántica que falta en una interfaz: qué es un elemento, cómo se llama, qué estado tiene y con qué contenido se relaciona. No crea automáticamente el comportamiento que anuncia. Un div con role="button" sigue necesitando foco, activación por teclado y lógica; un button ya aporta buena parte de esa base.

Para quién: desarrollo y revisión técnica. Antes de añadir atributos, identifica la tarea y el comportamiento esperado. Esta guía usa ejemplos didácticos independientes: al integrarlos en un producto, comprueba identificadores, estilos, compatibilidad y estados del recorrido completo.

Primera decisión: ¿HTML ya resuelve la necesidad?

NecesidadPunto de partidaQué revisar después
Ir a otra página<a href="…">Destino y nombre comprensibles.
Ejecutar una acción<button type="button">Resultado y estados de la acción.
Elegir una opción sencillainput o select con etiquetaInstrucciones, grupos y errores.
Mostrar información ampliadadetails y summaryTítulo del desplegable y utilidad de ocultar ese contenido.
Crear una interacción sin equivalente suficienteHTML adecuado más ARIA y JavaScriptPatrón completo: teclado, foco, relaciones y estados.

Evita reemplazar semántica válida por roles contradictorios o repetir todos los roles implícitos por costumbre. Un atributo ARIA solo debe aparecer si comunica información real, permitida para ese elemento y sincronizada con la interfaz. Un valor incorrecto puede empeorar lo que antes exponía correctamente el navegador.

Rol, nombre, descripción y estado

El rol identifica la clase de elemento. El nombre accesible permite distinguirlo: «Buscar guías». La descripción aporta ayuda adicional: «Busca por método, componente o problema». El estado cuenta lo que ocurre ahora, como expandido o pulsado. No incrustes «botón» en el nombre si el rol ya comunica que lo es.

Cómo elegir entre label, aria-label y aria-labelledby

  • Empieza con texto visible: contenido del botón, texto del enlace o un label asociado al campo mediante for e id.
  • Usa aria-labelledby para tomar el nombre de otro texto existente. Referencia identificadores únicos y vigentes. Puede combinar varios, en el orden indicado.
  • Usa aria-label cuando el elemento admite nombre y no hay texto visible adecuado que referenciar, por ejemplo un control formado solo por un icono. Sigue siendo preferible ofrecer una etiqueta visible cuando ayude a reconocer la función.
  • Usa aria-describedby para instrucciones o mensajes complementarios; no sustituye el nombre. Evita asociar párrafos enteros si una ayuda breve basta.
<label for="buscar-guias">Buscar guías</label>
<p id="ayuda-busqueda">Escribe un método, componente o problema.</p>
<input id="buscar-guias" name="s" type="search"
       aria-describedby="ayuda-busqueda">

Fragmento HTML implementable de un campo; para enviar una búsqueda debes integrarlo en un formulario con destino real. No añadas además un aria-label="Consulta": podrías sustituir el nombre visible «Buscar guías» por uno distinto. Para controles con etiqueta visible, WCAG 2.5.3 requiere que el nombre accesible incluya ese texto, lo que facilita activarlos mediante voz.

Estados y relaciones que conviene distinguir

AtributoQué comunicaError frecuente
aria-expandedSi el contenido controlado está expandido.Cambiar el panel sin actualizar true/false.
aria-controlsQué elemento controla este botón mediante su id.Pensar que crea por sí mismo la interacción o que siempre se anuncia igual.
aria-current="page"Cuál es la página actual dentro de un conjunto de enlaces.Usarlo como sustituto de selected en unas pestañas.
aria-pressedEstado de un botón de alternancia.Añadirlo a un botón de enviar que no conserva un estado.
aria-selectedSelección en roles que la admiten, como tab.Aplicarlo indiscriminadamente a enlaces o contenedores.
aria-disabledQue el control se expone como no disponible.Suponer que bloquea clics, envío o teclado; esa lógica debe implementarse.

Ejemplo completo: un desplegable con mejora progresiva

Este ejemplo mantiene la explicación visible si JavaScript no funciona. El botón solo aparece cuando puede abrir y cerrar el panel. Intro y Espacio funcionan por ser un botón nativo. No mueve el foco al abrir: la persona continúa desde el control.

<button type="button" id="ver-criterio" hidden
        aria-controls="criterio" aria-expanded="true">
  Criterio para considerar la tarea completada
</button>
<div id="criterio">
  <p>La persona llega a la confirmación sin ayuda del moderador.</p>
</div>
<script>
  const boton = document.getElementById("ver-criterio");
  const panel = document.getElementById("criterio");
  function mostrar(abierto) {
    panel.hidden = !abierto;
    boton.setAttribute("aria-expanded", String(abierto));
  }
  boton.addEventListener("click", () => {
    mostrar(boton.getAttribute("aria-expanded") !== "true");
  });
  mostrar(false);
  boton.hidden = false;
</script>

Para un simple bloque de información ampliable, details suele evitar este JavaScript. El ejemplo explica la sincronización necesaria cuando construyes el comportamiento tú mismo. Si el panel contiene controles y lo cierras desde otro lugar mientras el foco está dentro, devuélvelo antes a un destino lógico.

Mensajes de estado: informar sin secuestrar el foco

Una búsqueda que actualiza resultados necesita comunicar su resultado, pero no obligar a abandonar el campo. Una región role="status" suele ser adecuada para información no urgente; lleva implícita una prioridad cortés y lectura atómica. role="alert" está pensado para información importante y urgente. Usarlo para cada actualización genera interrupciones.

En una región live general, aria-live="polite" solicita anunciar cambios en un momento apropiado y assertive pide mayor prioridad. El anuncio concreto depende de la combinación de navegador y tecnología de apoyo. Crea la región antes de actualizar su texto y evita convertir toda la lista de resultados o toda la página en una región viva.

<button type="button" id="comprobar-demo">Comprobar selección de ejemplo</button>
<p id="estado-demo" role="status"></p>
<script>
  let veces = 0;
  document.getElementById("comprobar-demo").addEventListener("click", () => {
    veces += 1;
    document.getElementById("estado-demo").textContent =
      `Comprobación ${veces}: hay tres guías en esta selección de ejemplo.`;
  });
</script>

Demostración completa y local: el resultado es ficticio y no consulta una API. En una búsqueda real, escribe el recuento que devuelve la petición vigente y maneja también carga, cero resultados y error. No anuncies un éxito antes de que el servidor lo confirme. No añadas simultáneamente mecanismos redundantes de anuncio sin probar el resultado.

Oculto visualmente no significa fuera de la interacción

TécnicaPresentación habitualAccesibilidad e interacción
hidden normal o display:noneNo se muestra.Normalmente se excluye del árbol de accesibilidad y no recibe foco; evita CSS que contradiga hidden.
Clase para ocultar solo visualmenteQueda fuera de la lectura visual ordinaria.Puede seguir expuesto a tecnologías de apoyo; no debe dejar controles enfocables invisibles.
aria-hidden="true"No cambia el aspecto.Excluye el elemento y descendientes del árbol de accesibilidad; no impide por sí solo foco ni clic.
inertNo obliga a cambiar el aspecto.Desactiva la interacción y excluye el subárbol de la navegación por foco y del árbol de accesibilidad.

Usa aria-hidden con cuidado para información decorativa o redundante. No lo pongas en un control enfocable ni en un ancestro que contenga controles utilizables. Tampoco puedes recuperar un descendiente con aria-hidden="false" si un ancestro sigue oculto. role="presentation" elimina determinada semántica; no equivale a ocultar todo el contenido.

Foco y teclado forman parte del contrato

Antes de programar un widget, escribe qué hacen Tab, Mayús+Tab, Intro, Espacio, flechas y Escape cuando proceda. No todos los componentes usan todas las teclas. En un desplegable de navegación convencional, Tab recorre enlaces; en una lista de pestañas, las flechas cambian el foco entre pestañas y la selección sigue el modelo elegido.

No asignes role="menu" a la navegación del sitio solo porque se llama «menú». Ese rol implica un comportamiento de aplicación que suele ser innecesario para enlaces de páginas. Un nav, una lista y botones de expansión suelen expresar mejor la intención. No uses role="application" como arreglo general.

Cómo revisar tu implementación

  1. Inspecciona en el navegador el rol, nombre, descripción y estados calculados de cada control.
  2. Recorre el ejemplo solo con teclado, en ambos sentidos y con todos sus estados abiertos/cerrados.
  3. Confirma que cada referencia ARIA apunta a un id único y que lo anunciado coincide con lo visible.
  4. Prueba con JavaScript desactivado o fallido cuando hayas prometido mejora progresiva.
  5. Comprueba anuncios y navegación con las combinaciones reales de lector de pantalla que soporte tu producto. Documenta exactamente cuáles.
  6. Repite la revisión tras cargar datos, mostrar errores y cambiar el tamaño de ventana.

APG, la guía de prácticas de autoría de ARIA, ofrece patrones y ejemplos explicativos. Sus ejemplos no son una garantía de producción ni reemplazan las pruebas de integración. La pregunta de cierre es concreta: ¿puede la persona completar la acción y entender su resultado con la forma de interacción que utiliza?

Fuentes y siguientes pasos

PONLO EN PRÁCTICA

Tu próxima mejora empieza aquí.

Comprueba tu web y decide qué resolver primero.

Empezar la revisión