Enter The Dragon (Drop): reordenación de la lista accesible
Publicado: 2022-03-10A lo largo de los años de ser un desarrollador web centrado en la accesibilidad, me he ocupado principalmente de componentes de interfaz de usuario estandarizados y ampliamente adoptados, bien respaldados por tecnologías de asistencia (AT). Para este tipo de widgets, existen prácticas de creación de ARIA concisas, así como excelentes herramientas como axe-core que se pueden usar para probar los componentes web en busca de problemas de accesibilidad. Crear widgets menos comunes, especialmente aquellos que no tienen convenciones ampliamente adoptadas para la interacción del usuario, puede ser muy complicado.
Uno de los desafíos más difíciles con los que me he encontrado es la lista reordenable de arrastrar y soltar. Si bien una lista reordenable es un widget de uso común con convenciones intuitivas para usuarios de mouse, no está claro cómo los usuarios de tecnología de asistencia que solo usan teclado pueden realizar esta tarea simple. Debido a la ausencia de atributos ARIA admitidos, Dragon Drop utiliza regiones en vivo para transmitir la información necesaria para que todos los usuarios reordenen una lista.
Regiones en vivo
Las regiones activas son elementos HTML equipados con atributos ARIA que se pueden usar para notificar a los lectores de pantalla los cambios de contenido. ¡Nos permiten proporcionar un anuncio de lector de pantalla completamente personalizado sin tener que mover el foco! Las regiones en vivo son ideales para actualizaciones en tiempo real en partes remotas de la página, actualizaciones de estado e información urgente.
Se usan comúnmente en registros de chat, indicadores de progreso, actualizaciones de puntajes deportivos y alertas meteorológicas, pero deben usarse con moderación, ya que pueden crear fácilmente una experiencia demasiado detallada para los usuarios de lectores de pantalla. Si es nuevo en las regiones en vivo o simplemente desea explorar lo que pueden hacer, consulte mi zona de juegos de regiones en vivo, que le permite configurar su propia región en vivo personalizada.
Si desea utilizar regiones activas en su aplicación, consulte el módulo Región activa en npm.
<div aria-live="assertive" role="log" aria-relevant="additions" aria-atomic="true"></div>
¿Por qué usar regiones activas?
En un mundo ideal, hubiera podido simplemente confiar en los atributos ARIA de arrastrar y soltar aria-grabbed
-grabbed y aria-dropeffect
. Sin embargo, en realidad, la compatibilidad con estos atributos es rara y, cuando se admite, la experiencia es confusa y contradictoria para los usuarios de lectores de pantalla. Además de eso, estos dos atributos han quedado obsoletos desde ARIA 1.1, lo que significa que no veremos crecer el soporte para estos atributos en el futuro.
La conversación del W3C sobre esta obsolescencia se puede encontrar aquí. Debido a estos problemas, decidí no usar aria-grabbed
-grabbed y aria-dropeffect
en Dragon Drop. El soporte variable para los atributos de ARIA dentro de la amplia gama de emparejamientos de tecnología de asistencia/navegador es bastante frecuente en el mundo de la accesibilidad. Afortunadamente, los atributos de región en vivo como role
, aria-live
, aria-relevant
y aria-atomic
son bastante compatibles con lectores de pantalla como JAWS, NVDA y VoiceOver.
Accesibilidad optimizada
Dragon Drop es un módulo de reordenación de listas altamente configurable que funciona para usuarios de mouse, teclado y tecnología de asistencia. Hace un par de años, cuando decidí escribirlo, las listas de reordenación accesibles habían aparecido varias veces en proyectos en los que había estado trabajando, pero aún no había visto una solución funcional. De las docenas de complementos de reordenación de listas de arrastrar y soltar que encontré, la mayoría de ellos no fueron diseñados teniendo en cuenta la accesibilidad y, como resultado, eran muy inaccesibles.
Dragon Drop ha sido probado con VoiceOver, JAWS y NVDA y permite a los usuarios de AT reordenar una lista con éxito.
Me dispuse a responder todas las preguntas que cualquier usuario pueda tener al encontrarse con una lista reordenable. Estas preguntas han sido respondidas para los usuarios de mouse videntes a través de convenciones comunes, pero ¿qué pasa con el resto de los usuarios?
¿Cómo puedo recoger un artículo?
Al proporcionar un control que transmite el estado capturado de un elemento, junto con un texto de ayuda de nivel superior, podemos responder a esta pregunta. Por ejemplo, un control con el texto accesible (recopilado por AT a través de su nombre, función y valor) "Reordenar elemento 1, botón de alternancia" le dice al usuario que es un botón que, cuando se activa, recogerá el elemento y dará inicio a un reordenando
Dragon drop utiliza el atributo aria-pressed
para que los usuarios de AT sepan cuándo se está "arrastrando" un elemento y cuándo no. Se puede configurar para permitir que se pueda arrastrar un elemento completo, o simplemente un "controlador de arrastre" secundario, que en cualquier caso garantiza la presencia de role="button"
y tabindex="0"
.
Cuando se activa un elemento de arrastrar, se aplica aria-pressed="true"
al elemento y se lee un anuncio configurable, como "Elemento 1 capturado" a los lectores de pantalla a través de la región en vivo.
¿Cómo puedo mover un artículo?
Utilizando aria-describedby
para asociar los controles con texto de ayuda útil como "Active el botón de reordenar y use las teclas de flecha para reordenar la lista o use su mouse para arrastrar/reordenar". le dice al usuario cómo hacer el reordenamiento. Esto les permite a los usuarios de lectores de pantalla saber que cuando se presiona un elemento, las teclas de flecha hacia arriba y hacia abajo moverán el elemento hacia arriba y hacia abajo en la lista, respectivamente.
¿Cómo puedo dejar un artículo?
Debido a que se usa el atributo aria-pressed
, los usuarios pueden decir fácilmente cómo colocar un elemento. De alguna manera, forma o forma, todos los lectores de pantalla más utilizados transmiten el estado presionado de un botón de alternar. El atributo aria-pressed se establece en "falso" cuando se suelta un elemento y se lee un anuncio personalizado como "Elemento 1 eliminado" en los lectores de pantalla.
¿Cómo sé cuándo se ha reordenado la lista?
Cada vez que se utilizan las teclas de flecha hacia arriba y hacia abajo para modificar el orden de la lista, debemos asegurarnos de que todos los usuarios sean notificados de este cambio. Para los usuarios no videntes, debemos confiar una vez más en las regiones vivas. Un anuncio configurable como "La lista se ha reordenado, el artículo 1 ahora es el cuarto en la lista". , se lee para transmitir el estado actualizado de la lista reordenada. Esto es importante porque los usuarios videntes tienen una respuesta visual inmediata del orden alterado y esa misma información debe transmitirse a los usuarios de AT.
¿Cómo cancelo el nuevo pedido?
Dado que no podemos confiar en una convención ampliamente adoptada para dicha interacción, simplemente podemos incluir instrucciones como "Presione escape para cancelar el reordenamiento" dentro del texto de ayuda. Además, utilizamos la región en vivo para brindar una lectura personalizada que notifique al usuario sobre la cancelación.
Interacción del teclado
Llave | Conducta |
---|---|
Entrar o Espacio | Alterna el elemento entre los estados "agarrado" y "soltado" |
"↓" | Mueve un elemento "agarrado" hacia abajo en la lista |
"↑" | Mueve un elemento "agarrado" hacia arriba en la lista |
Esc | Cancela la reordenación y restaura la orden inicial |
Ver al dragón en acción
Consulte la demostración de Dragon Drop en la que experimenta un par de configuraciones diferentes.
Colocando Dragon Drop en tu aplicación
Dragon Drop convierte su lista ordinaria en una lista reordenable de arrastrar y soltar completamente accesible:
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <script> const dragon = document.getElementById('dragon'); // Enter the dragon new DragonDrop(dragon); </script>
Instalación
Dragon Drop es un proyecto de código abierto (Licencia MIT) y se puede instalar a través de npm:
$ npm install drag-on-drop
Se puede usar con módulos como browserify o webpack:
// if you're not down with ES6, you can require('drag-on-drop') import DragonDrop from 'drag-on-drop';
Dragon Drop también se puede colocar fácilmente en su página con el CDN unpkg:
<script source="https://unpkg.com/drag-on-drop"></script> <script> var dragonDrop = new DragonDrop(listElement); </script>
Configuración
Para admitir una amplia gama de casos de uso, Dragon Drop es muy configurable.
A continuación se muestra la configuración predeterminada:
{ item: 'li', handle: 'button', activeClass: 'dragon-active', inactiveClass: 'dragon-inactive', announcement: { grabbed: el => `Item ${el.innerText} grabbed`, dropped: el => `Item ${el.innerText} dropped`, reorder: (el, items) => { const pos = items.indexOf(el) + 1; const text = el.innerText; return `The list has been reordered, ${text} is now item ${pos} of ${items.length}`; }, cancel: 'Reordering cancelled' } }
Anuncios
La opción de configuración de "anuncio" de Dragon Drop es la más importante porque es la columna vertebral de la experiencia del lector de pantalla que proporciona Dragon Drop. Es un objeto que contiene funciones de "grabbed"
, "dropped"
, "reorder"
y "cancel"
que permiten anuncios de región en vivo personalizados para todas las interacciones que tienen lugar.
Cada una de estas funciones debe devolver una cadena de texto de anuncio que se agrega a la región en vivo cuando ocurre la acción dada. Un beneficio adicional de utilizar estas funciones es que admite la localización de los mensajes de la región en vivo.
Para facilitar los anuncios, el elemento del elemento de la lista en el que tuvo lugar la acción y la matriz de elementos de la lista se pasan como argumentos, respectivamente.
{ announcement: { // grabbed is called when an item is picked up grabbed: (targetItem, items) => `${targetItem.innerText} grabbed`, // dropped is called when an item is dropped dropped: (targetItem, items) => `${targetItem.innerText} grabbed`, // reorder is called each time the order of the list is altered reorder: (targetItem, items) => { return `${targetItem.innerText} is now ${items.indexOf(targetItem) + 1} of ${items.length}` }, // cancel is called when a reordering is cancelled (via escape key) cancel: () => 'The initial order has been restored, reordering cancelled' } }
texto de ayuda
Es absolutamente vital que proporcione un texto de ayuda que describa cómo usar la lista reordenable. Esto es algo que Dragon Drop no hace por usted para permanecer menos obstinado en cómo este texto se pone a disposición de la tecnología de asistencia. La implementación recomendada es usar aria-describedby
para asociar el texto de ayuda con los elementos interactivos de la siguiente manera:
<p>Activate the reorder button and use the arrow keys to reorder the list or use your mouse to drag/reorder. Press escape to cancel the reordering.</p> <ul> <li> <button>Reorder Item 1</button> <span>Item 1</span> </li> <li> <button>Reorder Item 2</button> <span>Item 2</span> </li> <li> <button>Reorder Item 3</button> <span>Item 3</span> </li> </ul>
Caída del dragón en GitHub
Recientemente se ha lanzado la tercera versión de Dragon Drop. Si está interesado en usarlo, consulte la documentación de Dragon Drop en GitHub. ¡Un agradecimiento especial a los creadores de Dragula, el módulo que Dragon Drop usa para la interacción con el mouse, así como a Aaron Pearlman, quien diseñó el increíble logotipo!
El futuro del dragón
Si se agrega la interacción de arrastrar y soltar a la especificación técnica de WAI-ARIA en el futuro, el hecho de que Dragon Drop se base en una interacción no estándar y regiones en vivo podría cambiar. Continuaré realizando pruebas para asegurarme de que siga siendo compatible con tantos lectores de pantalla como sea posible y me mantendré actualizado con las últimas especificaciones de ARIA. Además, hay bastantes funciones en proceso, incluida la compatibilidad con pantallas táctiles/dispositivos móviles, así como listas de varias columnas (como tableros de sprint). Otra característica que puede agregarse en el futuro es un componente Dragon Drop React.
Actualmente, Dragon Drop se puede usar con React, como se muestra en la demostración a continuación, pero no es ideal porque React no detecta los cambios de DOM causados por el reordenamiento de la lista, lo que puede causar un comportamiento inesperado. Insto a cualquiera que encuentre errores en Dragon Drop, o incluso tenga ideas para funciones, a crear un problema en GitHub. ¡Todos los comentarios y contribuciones son bienvenidos y muy apreciados!