jueves, 14 de noviembre de 2013

Live Regions y WAI-ARIA. Cómo mejorar la accesibilidad de contenidos que se actualizan automáticamente

Última actualización: 01/08/2017, he añadido la novedad de WAI-ARIA 1.1, los Live Regions Roles (alert, log, marquee, status, timer)

En este artículo explico:

  • el problema de accesibilidad que pueden suponer las zonas de nuestras páginas que se añaden, eliminan, actualizan o modifican automáticamente sin intervención del usuario (llamadas Live Regions)
  • lo fácil que es solucionar este problema con el uso del atributo aria-live de WAI-ARIA en dicha región.
  • el uso correcto del atributo aria-live y otros relacionados: aria-atomic, aria-relevant y aria-busy.
  • incluyo un ejemplo detallado para que podáis ver las diferencias según los valores que indicamos en estos atributos
  • la compatibilidad con diferentes lectores de pantalla y navegadores

Comprender el problema para entender la solución

Imaginemos que tenemos una zona o varias zonas de nuestra página web cuyo contenido se añade, elimina, actualiza o modifica sin intervención del usuario. Es lo que llamamos una live region, una zona viva de la página.

Os enumero algunos ejemplos, podemos tener una zona en la cual...

  • ... se actualicen los resultados de determinados eventos deportivos, por ejemplo, cada vez que un equipo marca un gol,
  • ... haya un banner publicitario que vaya mostrando cada x minutos un anuncio diferente,
  • ... haya un contador, por ejemplo indicando los minutos que restan para que termine el tiempo de un examen,
  • ... se muestren mensajes importantes al usuario, por ejemplo errores de validación de un formulario a medida que el usuario rellena los campos del mismo,
  • ... se muestren los usuarios que están conectados en ese momento, por ejemplo los alumnos en línea en un curso online,
  • ... se muestren los nuevos mensajes de un chat, de Twitter o las últimas noticias desde una fuente RSS.

Podríamos seguir poniendo ejemplos, lo que tienen en común todas ellas es que se actualizan automáticamente mediante un evento externo, no porque el usuario lo solicite explícitamente, y cuando se realiza dicha actualización el usuario puede tener el foco en cualquier otra parte de la página.

Si puedes ver la página seguramente no tendrás problemas para percatarte del cambio que se efectúe en una live region. El problema surge cuando accedes a la página mediante un lector de pantalla, pues no serás conscientes de la actualización a menos que el lector de pantalla te la anuncie.

Este es por tanto el problema que queremos solucionar: queremos que el lector de pantalla pueda anunciarle al usuario que se ha producido un cambio en una zona dinámica de la página (live region), qué cambio ha sido y decidir cómo y cuándo queremos que se lo anuncie.

No está de más recordar que es además un requisito de accesibilidad necesario para alcanzar el nivel de adecuación A de acuerdo a las WCAG 2.0. El criterio de conformidad 4.1.2 Nombre, función, valor (nivel A), indica:

4.1.2 Nombre, función, valor: Para todos los componentes de la interfaz de usuario (incluyendo pero no limitado a: elementos de formulario, enlaces y componentes generados por scripts), el nombre y la función pueden ser determinados por software; los estados, propiedades y valores que pueden ser asignados por el usuario pueden ser especificados por software; y los cambios en estos elementos se encuentran disponibles para su consulta por las aplicaciones de usuario, incluyendo las ayudas técnicas. (Nivel A)

WAI-ARIA como solución

WAI-ARIA (WAI - Accessible Rich Internet Applications) es una especificación del W3C que proporciona una ontología de roles, estados y propiedades que se pueden utilizar para mejorar la accesibilidad y la interoperabilidad de los contenidos y aplicaciones web.

WAI-ARIA provides a collection of accessibility states and properties which are used to support platform accessibility APIs on various operating system platforms. Assistive technologies may access this information through an exposed user agent DOM or through a mapping to the platform accessibility API. When combined with roles, the user agent can supply the assistive technologies with user interface information to convey to the user at any time. Changes in states or properties will result in a notification to assistive technologies, which could alert the user that a change has occurred.

Accessible Rich Internet Applications (WAI-ARIA) 1.0

WAI-ARIA nos proporciona pues mecanismos para transmitir a los productos de apoyo la información sobre la función, los estados y las propiedades (y sus valores) de los componentes de interacción personalizados, así como las notificaciones sobre los cambios producidos en los mismos.

Los atributos de WAI-ARIA que nos permitirán identificar las live regions y definir cómo queremos que se anuncien las modificaciones que en ellas se llevan a cabo son:

  • aria-live: para identificar la live region y, mediante su valor, indicar cuándo queremos que se anuncien sus actualizaciones al usuario.
  • aria-atomic: para definir si queremos que se anuncie toda la región o solo las partes que han cambiado.
  • aria-relevant: para establecer qué tipo de actualización en la región queremos que se anuncie al usuario.
  • aria-busy: para detener o activar temporalmente el anuncio de la actualización cuando muchas partes de un mismo elemento van a ser modificadas, y de este modo esperar a que terminen de realizarse las modificaciones antes de anunciar el cambio.

Cómo usar correctamente aria-live, aria-atomic, aria-relevant y aria-busy

aria-live

Este atributo se añade a un elemento para indicar que es una live region, es decir, que su contenido se modifica y actualiza dinámicamente.

Mediante el valor del atributo podemos indicar cuándo queremos que el lector de pantalla anuncie los cambios al usuario:

  • aria-live="off": los cambios se anunciarán al usuario solo cuando el foco esté en esa región. Será adecuado usarlo cuando la actualización no es relevante, por ejemplo una rotación de imágenes en la cabecera.
  • aria-live="polite": los cambios se anunciarán al usuario pero sin interrumpirle, anunciará el cambio cuando termine la tarea que está llevando a cabo, por ejemplo cuando termine de escribir en un campo o termine de leer un contenido.
  • aria-live="assertive": los cambios se anuncian de inmediato, independientemente de lo que el usuario esté haciendo. Teniendo en cuenta que el anuncio puede desorientar a los usuarios o que estos no terminen la tarea que están realizando, solo debe utilizarse para mensajes y advertencias importantes, por ejemplo los mensajes de error de validación en un formulario.

aria-atomic

Con aria-atomic especificamos si queremos que se anuncie toda la región o solo las partes de la misma que han cambiado.

Si el valor del atributo es "true" el lector de pantalla anunciará la región como un todo, por el contrario, si es "false" (el valor por defecto) solo anunciará el nodo que ha cambiado.

aria-relevant

Con este atributo indicamos qué tipo de actualización de la live region deseamos que se anuncie al usuario:

  • aria-relevant="additions": anuncia los elementos que se añaden al DOM. Si el contenido que se añade es semánticamente relevante será importante anunciarlo, por el contrario, si es meramente decorativo no tiene sentido que se anuncie.
  • aria-relevant="removals": anuncia los elementos que se eliminan del DOM. Igual que en el caso anterior, es importante tener en cuenta si el elemento eliminado es relevante o solo decorativo. Por ejemplo, en un listado de amigos en línea, si un amigo se desconecta sería interesante anunciar que se ha eliminado de la lista.
  • aria-relevant="text": anuncia las modificaciones de texto.
  • aria-relevant="all": anunciará todo, es decir, los elementos añadidos, eliminados y las modificaciones de texto.

Si no se incluye el atributo aria-relevant, por defecto se anunciarán los nodos añadidos y las modificaciones de texto.

aria-busy

Por defecto su valor es "false". Este atributo se utiliza cuando muchas partes de un mismo elemento van a ser modificadas, entonces puedes poner el valor a "true" para que temporalmente no anuncie las modificaciones y, una vez que se hayan llevado a cabo, volver a ponerlo a "false" para que las anuncie.

Ejemplo ARIA: Live Region

Nuestra live region es una zona de "Últimas noticias" que se actualiza de forma automática, sin intervención del usuario. Cada 10 segundo se elimina la última noticia de la lista y se incluye una nueva al comienzo de la misma.

La página está en HTML5, pero no es obligatorio, puedes utilizar WAI-ARIA en (X)HTML también. El código HTML de la live region es:


<div id="#contenedor" role="complementary">
   <div id="noticias">
   <h2 id="liveLabel">Últimas noticias</h2>
   <p class="peq">Se actualizan cada 10 segundos</p>
           <div id="liveDiv"  role="log" aria-labelledby="liveLabel" 
                 aria-live="assertive" 
                 aria-atomic="true" 
                 aria-relevant="additions">
              [5 div con cada una de las noticias]
          </div>
    </div>
[...]
</div>           

Como se observa, al DIV que contiene las noticias se le han añadido los atributos:

  • aria-live="assertive", indica que es una live region y que queremos que anuncie sus modificaciones de forma inmediata.
  • aria-atomic="true", indica que queremos que nos anuncie toda la región. NVDA y JAWS nos leen la zona completa de noticias, es decir, las cinco noticias. Si lo hubiéramos puesto a "false" solo nos leería la nueva noticia (el nodo completo: título, fecha y descripción)
  • aria-relevant="additions", indica que queremos que nos lea solo los elementos que se insertan en el DOM, por ello nos lee solo la noticia que insertamos pero no la que eliminamos de la lista.

Al no incluir aria-busy, su valor por defecto es "false".

El rol aplicado es role="log", que identifica una región donde nueva información es añadida en un orden significativo y la información vieja puede desaparecer. Este rol implica que hay una relación entre la llegada de nuevos elementos y el orden de lectura, la información se añade solo al final y no en puntos arbitrarios. Los elementos con este rol tienen implícito un aria-live="polite"

Comprobar las diferencias según los valores definidos en los atributos

Para facilitar que podáis comprobar cómo cambia la forma de anunciarse la actualización de las noticias en función del valor de cada atributo, hay un formulario para que podáis modificar estos valores.

Los nuevos valores de los atributos se aplican a la live region sin necesidad de recargar la página.

En el caso de aria-busy, podéis modificar el valor para comprobar cómo anuncia o no los cambios según esté a "true" o a "false", pero hay que tener en cuenta que esto habría que programarlo dinámicamente, para que, mientras se llevan a cabo múltiples actualizaciones de una región dejará de anunciar sus cambios hasta que se completaran todas.

¿Cómo puedo comprobar el resultado?

Si tienes instalado un lector de pantalla solo tienes que abrir la página de ejemplo "Ejemplo ARIA: Live Región" y escuchar. Cada vez que se actualice una noticia te leerá la zona de noticias independientemente de dónde tengas el foco.

Si eres un desarrollador y no tienes instalado un lector de pantalla, puedes instalarte uno gratuito como NVDA o con versión de prueba como JAWS. Pero también puedes instalarte la extensión de Chrome ChromeVox que es muy útil para probar desarrollos con WAI-ARIA.

Una vez instalada la activas en "Herramientas > Extensiones" y abres la página del ejemplo: "Ejemplo ARIA: Live Región", podrás comprobar cómo te anuncia cada actualización de la zona de "Últimas noticias" según los valores definidos para los atributos de la región.

También es muy útil la extensión Accessibility Developer Tools, te permitirá evaluar si tu código ARIA es correcto. Para ello, una vez instalada, accedes a "Herramientas > Herramientas para desarrolladores > Audits" y haces la auditoría con la opción de "Accessibility" seleccionada. Te indicará por ejemplo si falla alguna propiedad ARIA o su valor no es adecuado.

Compatibilidad y diferencias entre diferentes lectores de pantalla

Funciona bastante bien con JAW15 corriendo en Firefox 25 y Explorer 10, sin embargo no funciona con JAW15+Chrome.

También funciona con VoiceOver en Chrome y Safari.

Con NVDA 2013 solo va cuando corre bajo Firefox 25, y además solo con aria-atomic="false", si el valor es "true" no lee nada. No funciona corriendo en Chrome y Explorer.

Hay una diferencia en cómo anuncia ChromeVox y JAWS los cambios de la región cuando aria-atomic="true". JAWS lee toda la región, es decir, todas las noticias. Sin embargo ChromeVox nos anuncia el título de la región, como está asociada al titulo "Últimas noticias" mediante el atributo aria-labelledby nos anuncia que se ha modificado "Últimas noticias".

Por otra parte ChromeVox parace ser el único que anuncia correctamente los nodos eliminados cuando aria-relevant es "removals" o "all", el resto de lectores no anuncian los nodos eliminados.

Si probáis con otros navegadores y/o lectores de pantalla os agradecería que pusierais vuestra experiencia en los comentarios.

Live Regions Roles (alert, log, marquee, status, timer)

¿Qué diferencia hay entre marcar un mensaje de error de estas tres maneras?

<p id="errors3" role="alert" aria-atomic="true"></p>

<p id="errors3" aria-live="assertive" aria-atomic="true"></p>

<p id="errors3" role="alert" aria-live="assertive" aria-atomic="true"></p>

Puedes ver un ejemplo en la página: Simple Form Validation Using Only WAI-ARIA role=alert or aria-live=assertive

role=alert funciona como aria-live con la ventaja de que precede el anuncio de la palabra "alerta".

Se puede usar sin aria-live y se le pueden añadir los atributos aria-atomic, aria-busy y aria-relevant

La ventaja de usarlo con aria-live es que podemos indicar cuándo queremos interrumpir al usuario y aumentamos la compatibilidad con los navegadores. aria-live tiene mejor soporte en JAWS y ChromeVox que en NVDA, donde funciona mejor con Firefox. role=alert está también soportado por IE.

La nueva versión de WAI-ARIA (la 1.1), trae una novedad, define un nuevo tipo de roles, los Live Regions Roles, es decir, aquellos a los que se pueden aplicar los atributos de las live regions:

  • role="alert": contiene información relevante y se anuncia con “alerta”. Debería ser aria-live="assertive"
  • role="log": donde la información se agrega en orden significativo y la antigua puede desaparecer, debería ser aria-live="polite"
  • role="marquee": información no relevante que cambia con frecuencia, debería ser aria-live="off"
  • role="status": advertencia no lo suficientemente importante para justificar una alerta, debería ser aria-live="polite"
  • role="timer": contador numérico del tiempo transcurrido o restante

Referencia en WAI-ARIA 1.1: 5.3.5 Live Region Roles

WAI-ARIA 1.1 es recomendación desde el 14/12/2017. Puedes consultar todas las novedades en el artículo: Novedades WAI-ARIA 1.1

Enlaces de interés

Artículos relacionados

Servicios de accesibilidad que ofrezco como consultora freelance

3 comentarios :
Alejandro Cañizares dijo...

Muy interesante la información, gracias por su publicación.

Bárbara Velásquez dijo...

Buenas! Muy buen artículo. Aprovecho de hacerle una consulta: tengo entendido que a partir de la versión 2020.4 de NVDA se hicieron mejoras en la interpretación de atributos aria para live regions ¿Sabe usted si estas mejoras se extendieron para chrome, o sigue siendo preferible testear con firefox? Gracias de antemano. Saludos desde Chile!

Olga Carreras dijo...

Puedes testear con Chrome, el soporte actual es bueno.

Publicar un comentario