¿Arrastrar y soltar componentes para usuarios ciegos? Estas bromeando

¿Qué une a Trello, Gmail, Aviasales y Google Keep? Cada uno de ellos tiene componentes de arrastrar y soltar que se pueden arrastrar con el mouse. El uso de estos componentes hace que los sitios web sean realmente convenientes, porque en la vida real a menudo usamos este patrón. Es natural para nosotros mover cosas, así que en la web queremos mover elementos alrededor de la pantalla de un lugar a otro, como pegatinas en una pizarra o imanes en un refrigerador. Ordenar listas de tareas, organizar paneles, descargar archivos: simplemente no podemos imaginar todos estos eventos sin arrastrar y soltar elementos en la página.



Pero hay un matiz. Cuando desarrollamos dichos componentes, creemos que nuestros usuarios ven físicamente la pantalla y los elementos, pueden atraparlos con el mouse y arrastrarlos. A menudo lo es, pero nos olvidamos del segmento de usuarios con problemas de visión. Creamos componentes que no pueden ser utilizados por un gran grupo de personas que simplemente no los ven. ¿Cómo hacer que los componentes de arrastrar y soltar también sean accesibles para ellos?

Sergey Krieger es desarrollador front-end en SinnerSchrader. Además del desarrollo front-end, está activamente interesado en el tema de accesibilidad web y hablará sobre algunas formas de aumentarlo. Debajo del corte, una historia sobre la creación de componentes de arrastrar y soltar para aquellos que no ven la pantalla y usan otros dispositivos para interactuar con el navegador.


Control deslizante


Comencemos con una pantalla simple en la pantalla del sitio de Aviasales. Ingrese el punto de partida, el punto de llegada y la lista de vuelos para la selección aparece en la pantalla. Puede haber muchos vuelos, se pueden filtrar por precio, tiempo y otros parámetros. Los controles deslizantes se utilizan para filtrar resultados en el sitio web de Aviasales. Se ven geniales, son convenientes de usar.



Nuestra tarea es imaginar que somos los desarrolladores de este sitio. Intentemos recrear estos controles deslizantes y ver cómo funcionan en diferentes casos.

Control deslizante nativo


Lo primero que debe pensar es si los elementos nativos se pueden utilizar para nuestra funcionalidad. Si existe esa oportunidad, vamos por este camino, porque los elementos nativos ahorrarán mucho tiempo.

Hagamos un ejemplo simple: el control deslizante se mueve a lo largo de la pista y el valor del control deslizante cambia. Mueva el control deslizante hacia la derecha: el color de la pantalla cambia de blanco a rosa brillante, si está atrás, nuevamente a blanco.



El control deslizante funciona simplemente: el control deslizante se desliza a lo largo de la pista y el control deslizante devuelve algún valor.

Nadie usará un control deslizante de este tipo en la producción. Ningún diseñador le permitirá usar, porque se ve débil. Nosotros, como desarrolladores, podemos resolver este problema. Hay una serie de propiedades CSS con prefijos para cada navegador, donde puede estilizar elementos individuales del control deslizante y refinarlo.

: : -webkit-slider-runnable-track : : -webkit-sHder-thumb : : -moz-range-track : : -moz-range-thumb : : -ns-track :-ms-thumb : : -ms-fill-lower : : -ms-fill-upper 

Puede usar las propiedades manualmente, pero esta no es una tarea trivial. Las propiedades funcionan en diferentes navegadores, y las pruebas tomarán mucho tiempo.

Pero hay una herramienta especial que resuelve el problema: el sitio web de Daniel Stern . Puede aplicarle estilo manualmente al control deslizante, copiar el código CSS y todo funciona. El control deslizante nativo ahora es un elemento HTML de input con el range tipos, pero funciona como antes, moviendo el control deslizante.

Prueba deslizante


Para resolver el problema hasta el final, lo probamos. Además, probaremos no solo el control deslizante, sino también otros elementos en tres parámetros.

  • El raton . Probar el funcionamiento del componente con el mouse es exactamente lo que siempre hacemos.
  • Teclado Además del mouse, adaptamos el control deslizante para personas con problemas de visión. Estos usuarios no ven la pantalla y usan el teclado para interactuar con la computadora y el navegador
  • Lector de pantalla : un dispositivo especial que lee la información en la pantalla.

Nota: en lo sucesivo, es más conveniente combinar las pruebas de lectura y visualización en grabaciones de video; esto es más obvio. Un segmento de video con prueba del control deslizante comenzará en el momento correcto.


El raton . Nos aferramos al control deslizante, tiramos hacia la derecha y hacia la izquierda. Si todo cambia, genial.

Teclado Use la tecla Tab para ir al control deslizante y use las flechas para moverlo a lo largo de la pista.

Lector de pantalla . Es más complicado aquí. Imagine que no vemos la pantalla: apague la luz de la pantalla y encienda el lector de pantalla. El dice:

- VoiceOver está activado en Chrome .

Usando la tecla Tab, vaya al control deslizante.

- Cero. Aplicación deslizante estilizada.

El lector de pantalla expresa información: valor, nombre del control deslizante y otra información relacionada, que también puede ser útil. Comenzamos a mover el control deslizante:

- Uno, dos, tres, cuatro, cinco.

Si escuchamos la cuenta regresiva, todo funciona. Encienda la luz y verifique el resultado. La prueba ha terminado.

Parece que no hicimos nada, simplemente estilizamos el control deslizante. ¿Cuál es nuestro trabajo sobre accesibilidad? El hecho es que no había trabajo: utilizamos el elemento nativo.

Si su aplicación tiene la capacidad de usar elementos nativos: control deslizante, botones, casillas de verificación, siéntase libre de usarlos y ahorre tiempo. Estos elementos ya admiten el teclado y el lector de pantalla.

Control deslizante personalizado


Supongamos que el control deslizante nativo no es nuestra opción. Miremos el código de Aviasales y veamos que aquí no están los controles deslizantes que acabamos de probar.



Esta no es una input con el range tipos, sino un conjunto de div estilo deseado por el diseñador. Parece que no hay diferencia, todo funciona.

Comprobaremos esto y complicaremos de manera similar la tarea creando manualmente un control deslizante. La clave para mover el control deslizante a lo largo de la pista es el posicionamiento absoluto:

 position: absolute 

Posicionamos absolutamente el control deslizante en relación con la pista y, dependiendo de su posición, calculamos el valor del control deslizante.

Para determinar el momento de captura de un elemento con el mouse, usamos el evento mousedown . Para seguir el movimiento del evento, mousemove y mouseup nos dirán que lanzamos el control deslizante. Para la pantalla táctil, también usaremos una serie de eventos: touchstart , touchmove y touchend .

Parece que todo es simple. El control deslizante se verá igual que en el ejemplo anterior, pero en el código no es un control deslizante, sino un conjunto de div estilizadas, y JavaScript será responsable de moverlo. Al trabajar con un mouse, esto será imperceptible, pero hay un matiz con el teclado. Para que el teclado pueda atrapar ese control deslizante, le damos la propiedad de enfocarse con el atributo tabindex y usar JavaScript para rastrear el clic en las flechas.

Prueba del control deslizante personalizado



Con un lector de pantalla será más difícil. Apague la luz, encienda el lector de pantalla e intente cambiar el valor. El lector de pantalla expresa las acciones, y si dice algo extraño, por ejemplo, "grupos", pensamos.

"Grupos" es lo que expresa el lector de pantalla cuando lee un elemento div u otro elemento que no tiene ningún papel semántico. Cualquier palabra que no se refiera al control deslizante dice que la accesibilidad aún no se ha logrado. Para que el control deslizante esté disponible, utilizamos los atributos ARIA:

 <div class="thumb" tabindex="0"    role="slider"    aria-labl=""    aria-valuenow="5"    aria-valuemin="0"    aria-valuenax="10" ></div> 

Necesitamos decirle al lector de pantalla que nuestro elemento de estilo habitual es un control deslizante. Haremos esto usando el role con el slider valor. Luego asigne el nombre al control deslizante utilizando el aria-labl . Establecemos el valor actual del control deslizante, el valor mínimo y máximo del control deslizante. Usando estos cinco atributos ARIA, animaremos el control deslizante y haremos que el lector de pantalla diga lo que necesitamos.

Mediante elementos de marcado, JavaScript y ARIA, pusimos el control deslizante personalizado a disposición de todos los usuarios.

Clasificación


Otro enfoque para implementar componentes de arrastrar y soltar es la ordenación. A menudo, los sitios tienen listas de elementos que son buenos para ordenar.



Arriba hay una captura de pantalla del sitio web de Google Keep: es un servicio que le permite crear listas de tareas, hojas de tareas. Una hoja de tareas tiene un nombre, una lista de elementos, la capacidad de marcar cada elemento, eliminarlo y agregar uno nuevo. Nuestra tarea es recrear esta funcionalidad.

Así es como se ve el widget de la lista de tareas.



Tiene:

  • nombre - lista de tareas;
  • Elementos: caminar con el perro, hacer una cita con el médico, que se puede anotar o eliminar;
  • la capacidad de agregar nuevos elementos: agregar una tarea.

Cuando agregamos un elemento nuevo, como "preparar la cena", se coloca al final de la lista. Este es un comportamiento lógico: agregamos el elemento en último lugar. Pero supongamos que estas listas tienen algún tipo de prioridad. Por ejemplo, después de un día de trabajo, la cena es más importante que caminar con un perro. Nos gustaría moverlo al principio: los elementos prioritarios deben estar en la parte superior de la lista. ¿Cómo resolver este problema?

¿Cómo mover elementos, incluso sin pensar en la accesibilidad? Ya conocemos una forma: utilizar el posicionamiento absoluto. Otra forma es agregar el atributo draggable a los elementos. Si agrega este atributo a true cualquier elemento, se vuelve arrastrable. Puede agarrarlo con el mouse y arrastrarlo a otra ubicación en la pantalla.

Pero no todos los elementos necesitan el atributo draggable . Las imágenes y los enlaces no son necesarios: se arrastran y sueltan de forma predeterminada.

Solo si queremos cancelar esta funcionalidad, configuraremos draggable con valor false .

Transferencia de datos


Hay dos elementos en la pantalla. A la izquierda hay una imagen en la que el atributo draggable está implícito de forma predeterminada. A la derecha hay un elemento con una línea discontinua. Nuestra tarea es arrastrar la imagen dentro del cuadrado punteado, que llamé "zona de caída".



Tome la imagen y arrástrela hacia la zona de colocación. Esta funcionalidad familiar: podemos ingresar la imagen en la zona de arrastre, salir cuando se suelta: la imagen está adentro. Queremos la misma funcionalidad en nuestra lista de tareas pendientes.



Pero antes de ver cómo funciona la lista de tareas con esta tecnología, descubriremos qué sucede cuando arrastramos un elemento de un lugar a otro. Una lista de eventos ocurre en cada uno de estos elementos.

Hay tres eventos en un elemento arrastrado.

Dragstart , que ocurre una vez cuando comenzamos el proceso de arrastrar un elemento. Este es un evento importante, luego descubriremos por qué.

Un arrastre que ocurre regularmente cada pocos cientos de milisegundos. Dependiendo del navegador, el valor cambia, pero el evento es frecuente. Con este atributo, puede rastrear la posición en la pantalla del elemento que estamos arrastrando.

Dragend : se dispara cuando lanzamos un elemento con el mouse.

En un elemento que acepta otros elementos, se disparan cuatro eventos.

Dragenter : alerta cuando arrastramos un elemento dentro de otro elemento.

Dragover - dice cuando comenzamos a moverlo adentro.

Arrastrar : cuando movemos un elemento más allá de los límites de otro elemento, sin soltar el mouse.

La caída es el evento más importante que se dispara cuando liberamos el mouse dentro del elemento receptor.

Todos estos 4 eventos son solo requisitos previos para el movimiento del elemento: ellos mismos no hacen nada. Utilizándolos, puedes decidir el movimiento de un elemento. Lo hacemos así:

 draggable.addEventListener("dragstart", e => { e.dataTransfer.setData("text/plain", e.target.id); }); dropZone.addEventListener("drop", e => { const id = e.dataTransfer.getData("text/plain"); const el = document.getElementById(id); }); 

Podemos agregar datos manualmente al evento que se dispara al principio en el elemento que estamos arrastrando. Usando el método dataTransfer.setData , agregamos el selector del elemento que estamos arrastrando. En nuestro caso, esto es id .

Al final, cuando el evento Drop se desencadena en el elemento receptor, obtenemos estos datos utilizando el método dataTransfer.getData . Resulta que tendremos la id elemento que queremos mover. Luego, usando JavaScript ordinario, seleccione este elemento en la página y muévalo a cualquier lugar. Nos movemos a mano. Para hacerlo posible, utilizamos eventos en el elemento de arrastrar y soltar.

Podemos arrastrar cualquier elemento sobre cualquier otro elemento. Simplemente arrastre el elemento alrededor de la página y apúntelo a los demás. Mover no significa que un elemento deba aceptar otro si no se planificó. Por lo tanto, los navegadores funcionan de esta manera: por defecto, ningún elemento puede aceptar otros.

Si queremos enseñarle al elemento a aceptar a otros, debemos cancelar este valor utilizando el método e.preventDefault() en dragenter y dragover , que se dropZone en el elemento dropZone .

 dropZone.addEventListener("dragenter", e => { e.preventDefault(); }); dropZone.addEventListener("dragover«, e => { e.preventDefault(); }); 

Probé esta combinación en diferentes navegadores. Por ejemplo, solo dragenter funciona en Chrome, así que use dragenter y dragover para una solución de navegador cruzado.

Veamos cómo funciona esto en la lista de tareas pendientes.



Nuestra tarea es arrastrar el último elemento de la lista de tareas a la primera posición. Desplácese sobre un elemento y un elemento con 6 puntos verticales aparece a la izquierda. En el mundo UX, esto significa que puedes arrastrarlo.



Pasamos el cursor sobre él y, si cambia, es una señal de que el elemento está listo para moverse. Tire hacia arriba con el mouse y aparecerá un indicador rosa, que indica dónde puede mover el elemento. El resto de la técnica es colocar el objeto en la posición deseada.



Ahora le enseñaremos al teclado y luego al lector de pantalla a procesar correctamente lo que acabamos de hacer.

Teclado


Con el teclado, todo no es tan complicado. Con el teclado, usamos el mismo patrón que para el mouse: encontramos el elemento que queremos mover, seleccionar, mover y luego soltar, y se ajusta en su lugar.

Presione Tab y aparecerá un icono familiar de 6 puntos a la izquierda del primer elemento, que dice que puede arrastrar y soltar. Por defecto, está oculto y su apariencia significa que se ha enfocado. Esta es una señal de que puede interactuar con este elemento.

Introducimos el primer elemento "cocinar la cena" en el "modo de selección" presionando "Enter". Este artículo actualmente está recibiendo opciones adicionales. Las flechas hacia arriba y hacia abajo pueden moverlo a otras posiciones. Presione la flecha hacia abajo, el elemento se mueve una posición, una vez más a otra. Entonces, movemos manualmente el componente. Este no es el valor predeterminado en el navegador: lo escribimos manualmente en JavaScript.



Cuando deseamos eliminar la selección del elemento, presione "Esc" o cualquier otra tecla: el elemento pierde la selección y permanece en el lugar correcto.

Lector de pantalla


Todo está claro con el teclado. Casi solucionamos el problema. Queda por enseñar al lector de pantalla a pronunciar acciones. Todo lo que se necesita es agregar instrucciones para que el lector de pantalla sepa lo que está sucediendo: dónde está y qué hacer.

Para controlar lo que dice el lector de pantalla, utilizaremos la tecnología Live region. Este es un conjunto de atributos que se pueden agregar a los elementos. Dependiendo de los atributos, el lector de pantalla pronuncia diferentes frases.

 <div class="live-region visually-hidden"    aria-live="polite"    role="status" ></div> 


 const liveRegion = document.querySelector(".live-region«); liveRegion.textContent = ' '; 

Establecí el atributo aria-live con un valor de polite div vacío regular, y el role con un valor de status . Para un lector de pantalla, esta es una señal para escuchar un elemento. Cuando desee que el lector de pantalla diga algo, actualice el contenido usando JavaScript, y el lector de pantalla dirá ese contenido.

Veamos como funciona.


Nuestra tarea es mover el primer elemento a la última posición. Apague la luz en la pantalla, encienda el lector de pantalla.

- VoiceOver está activado en Chrome.

Comenzamos a mover el artículo. Primero, busque nuestro widget: avance por los encabezados. Voces del lector de pantalla:

- Encabezado nivel dos. Lista de tareas

Lo encontré Continuamos haciendo clic en la tecla Tab.

- Lista de objetos 3. Presione la tecla “Enter” para seleccionar el elemento “Caminar con el perro”. Grupos.

Primero, el lector de pantalla pronuncia el número de elementos en la lista, para que los usuarios entiendan cuántos elementos hay en la lista. Luego pronuncia una instrucción: qué hacer para seleccionar un elemento: "Presione la tecla Intro y el nombre de este componente. Quedó claro qué hacer: presione la tecla Intro.

- Se selecciona el elemento "Pasear con el perro". Usa las teclas Arriba y Abajo para moverte. Use la tecla Esc para anular la selección.

Hablé de estas instrucciones: cuando selecciona un elemento, el lector de pantalla da las instrucciones que se nos ocurrieron. Actualizamos el lector de pantalla y pronuncia el texto que colocamos en el elemento Región en vivo. Con las instrucciones, queda claro qué hacer: use las teclas Arriba / Abajo y Esc para anular la selección. Moverse hacia abajo una posición.

- El elemento "Pasear con el perro" se mueve a la posición 2.

Una vez mas

- El elemento "Pasear con el perro" se mueve a la posición 3.

El artículo está al final de la lista. Encienda la luz y verifique si el elemento está realmente en la última posición.

Presione "Esc" para anular la selección.

- El elemento "Dar un paseo con un perro" se ha deseleccionado.

Con la ayuda de la imaginación, el marcado, los atributos de JavaScript y ARIA, pusimos a disposición un widget que es difícil para los usuarios con problemas de visión.

En movimiento


Echemos un vistazo a los elementos en movimiento alrededor de la página usando Trello como ejemplo. Este es un rastreador de tareas con columnas que indican el estado de las tareas. Arrastrar y soltar tareas de una columna a otra corresponde a un cambio en el estado de la tarea.



Simule una versión simplificada de Trello para descubrir cómo hacer que este componente esté disponible. En mi versión hay tres columnas: "Lo haré", "Lo hago", "Hecho".



Las tareas se pueden arrastrar de un lugar a otro: agarre el componente con el mouse, arrástrelo a la siguiente columna, suéltelo; permanece allí.

Teclado


Todo es simple con el mouse; estamos familiarizados con el atributo draggable con el valor true del ejemplo anterior. Con el teclado era posible hacer la misma opción: mover la tarea de columna a columna con flechas. Pero, si las columnas son 5 u 8, entonces pasar de la primera a la última requerirá 5 u 8 clics en la tecla Derecha 5 u 8 veces, lo cual es inconveniente y dificultará el trabajo con el componente.

Haremos lo contrario. Presione la tecla Tab, el foco se mueve al primer elemento. Presione la tecla nuevamente y aparece un nuevo elemento que estaba oculto hasta que el foco se movió hacia él.



Tres puntos verticales significan que el elemento tendrá un menú. El ícono puede ser diferente. El comportamiento predeterminado del navegador cuando se trabaja con el elemento select es hacer clic en el "Espacio", después de lo cual aparece un menú.

Resolveremos el problema usando JavaScript, pero daremos a los usuarios la oportunidad de elegir qué columna quieren mover esta o aquella tarea.



Nos movemos a la última columna, presionamos "Enter", y todo funcionó: el elemento se movió a donde queríamos.

Lector de pantalla


Agregue instrucciones para el lector de pantalla. El uso del elemento de select regular ofrece una gran ventaja porque está disponible de forma predeterminada. Veamos que podemos hacer.


Apague la luz en la pantalla, encienda el lector de pantalla.

- VoiceOver está activado en Chrome.

Pasamos al primer elemento. El lector de pantalla dice cuántos objetos hay en la lista. Usamos la elementos semánticos y el nombre del elemento. Presione Tab.

- "Hacer": seleccione el botón emergente contraído del botón "Play Soccer", grupos.

El lector de pantalla puede pronunciar palabras extrañas. Él llama al nombre de la columna "Make", y "pop-up minimizado" para el lector de pantalla significa que usaremos el menú - para el usuario del lector de pantalla esto estará claro. "Minimized", "pop-up" y "button" se pronunciarán de manera diferente en diferentes lectores de pantalla, pero no tenemos que preocuparnos mucho por eso, porque los usuarios de lectores de pantalla están familiarizados con este comportamiento.

Nuestra tarea es seleccionar la columna deseada de la lista.

- No es cero, hazlo. Seleccione la columna desplegable desplegable, botón. Su posición actual en la pantalla ... "Haciendo". "Listo" ... El elemento "Jugar al fútbol" se ha movido a la columna "Listo".

Este es el texto que agregamos manualmente para informar a los usuarios que lo hicimos. Así es como funciona nuestro tablero de tareas.

Subir archivos


La funcionalidad de carga de archivos también se encuentra en los sitios, por ejemplo, para adjuntar archivos a un correo electrónico. Por lo tanto, en mi ejemplo, el correo electrónico es Gmail.



Hay un elemento con una línea discontinua en la pantalla. Aquí es donde arrastraremos nuestros archivos.



Para hacer esto, abra el explorador donde se encuentran los archivos y arrastre el archivo con el mouse a la zona punteada. Después de arrastrar y soltar, el elemento cambia de estado, suelta el archivo y comienza la descarga. Al final de la descarga, notificaremos al usuario que todo se ha descargado correctamente.

Teclado


Con el teclado, todo se resuelve de manera simple. Hay un elemento de input semántico de tipo file . Si lo usa, cuando haga clic en este elemento, el cuadro de diálogo Explorador se abrirá automáticamente donde podrá seleccionar archivos del sistema operativo. Los estilos de ventana se pueden configurar absolutamente cualquiera, dependiendo de los deseos de su diseñador.



Haga clic en el elemento, se abre un cuadro de diálogo. Como usamos el elemento de input nativo, también puede moverse a este elemento con la tecla Tab, presionar la barra espaciadora y se abrirá un cuadro de diálogo. Los elementos se seleccionan con la tecla Intro, y todo sucede de la misma manera.

Todo funciona con el mouse y el teclado. Para el lector de pantalla, puede hacer algo que, de manera predeterminada, no es proporcionado por elementos nativos.

Lector de pantalla


El elemento "select" funcionará y aún podemos abrir un cuadro de diálogo con el sistema operativo. Pero cuando comienza la carga, podemos hacer algo muy interesante para actualizar el lector de pantalla del usuario sobre el estado de la descarga.


Enciende el lector de pantalla. Con el teclado, vaya al elemento para seleccionar archivos del sistema operativo.

- Seleccionar aplicación de botón.

Presione el botón con el lector de pantalla.

- Presione el botón de selección. El comienzo del diálogo ... Image image.png. 31 de marzo ... 0% ... 16% descargado ... 73% descargado ... 100% cargado. El archivo image.png se ha cargado correctamente.

Que paso Después de abrir el cuadro de diálogo, seleccionamos el archivo. No necesitamos hacer nada aquí, porque el lector de pantalla está relacionado con el sistema operativo y no tiene nada que ver con el navegador. El sistema de archivos, como todas las demás aplicaciones, pueden manejarse bien.

, screen reader . — 10%, 20%...100%. , , , .

Live region, . screen reader, , ARIA Live, screen reader . .

Resumen


. — . , , screen reader. , , .

HTML + JavaScript + ARIA . Drag-&-Drop , JavaScript ARIA. , .

« » . , « »: , , , , .

. : , , .


, W3.org — . .

, , inclusive-components.design . . , , , , , .

. , , « ». — . .

. , — Medium . , . , . , , . . , .

. FrontendConf ++ . FrontendConf 2019 Leonie Watson — , W3C W3C -. Leonie screen reader. , , , , .

FrontendConf , . , .

Source: https://habr.com/ru/post/468541/


All Articles