Accesibilidad en Carruseles: Manejo de Foco con TabIndex
Resumen
¿Cómo manejar el atributo tabindex para la accesibilidad en nuestros proyectos?
En el diseño web moderno, la accesibilidad es una prioridad que no debe olvidarse, especialmente en componentes interactivos como los carruseles. Aquí aprenderás a utilizar el atributo tabindex para mejorar la accesibilidad de tus proyectos web y asegurar que los usuarios, independientemente de la forma en que naveguen por tu sitio, tengan la misma experiencia.
¿Qué es el atributo tabindex y cómo se utiliza?
El atributo tabindex indica si un elemento puede ser enfocado y si participa en la navegación secuencial del teclado. Es un método indispensable para controlar el enfoque de elementos HTML.
Valores de tabindex:
Negativo (-1): El elemento puede ser enfocado, pero no es accesible mediante la navegación secuencial. Útil para elementos ocultos visualmente.
Cero (0): El elemento debe ser enfocado y es accesible a través de la navegación secuencial según la estructura normal del HTML.
Positivo (>0): Define un orden específico de navegación; se utiliza con cautela para evitar romper la lógica del sitio.
Implementación de tabindex en un carrusel accesible
Al crear un carrusel accesible, es importante considerar tanto los usuarios que navegan con teclado como aquellos que lo hacen con dispositivos de entrada tradicionales como el mouse. Veamos un ejemplo práctico de cómo implementar tabindex:
// JavaScript para manejar el cambio de focolet currentElement =/* elemento actual del carrusel */;if(currentElement ===/* condición para mostrar otro elemento */){document.querySelector('.proyecto-uno').setAttribute('tabindex','-1');document.querySelector('.proyecto-cuatro').removeAttribute('tabindex');}
¿Cómo utilizar tabindex de forma segura y efectiva?
Es importante recordar que la interacción debe ser igual para todos los usuarios, sin importar el modo de navegación.
Ocultar elementos del navegador: Usa tabindex con valores negativos para elementos que deben permanecer en el DOM pero no visibles.
Estructura secuencial sensata: Evita valores positivos a menos que estés seguro de que no desordenen el flujo natural del documento.
Prueba el componente con diferentes dispositivos y herramientas de accesibilidad para garantizar que la navegación se mantenga funcional y accesible.
¿Cómo sincronizar tabindex con aria-hidden?
En las siguientes etapas del desarrollo del carrusel, es crucial asegurarse de que los lectores de pantalla no lean los elementos ocultos. Esto se puede lograr coordinando sabiamente tabindex con atributos como aria-hidden.
Mantente atento a los detalles de accesibilidad, ya que mejorarás significativamente la experiencia del usuario y cumplirás con las normativas necesarias para la inclusión digital. Recuerda que la accesibilidad es un componente no negociable del diseño web contemporáneo, y su implementación adecuada refleja un cuidado por todos los usuarios.
Tabindex: Indica si su elemento puede ser enfocado, y si participa en la navegación secuencial del teclado.
Valores de Tabindex:
Valor negativo(-1): El elemento debe ser enfocado, pero no debe de ser accesible a través de la navegación.
Valor positivo (>0): Debe poder ser enfocado y su orden relativo es definido por el valor del atributo.
Valor de 0: Debe ser enfocado y ser accesible a través de la navegación secuencial del teclado, pero su orden relativo es definido por convención de la plataforma.
Excelente resumen!
thanks for the summary
wow... solo hasta cuando uno mismo empieza a hacer el proyecto se da cuenta la cantidad de cosas que pasan desapercibidas para que la página aparezca aparentemente "sencilla" y de fácil accesibilidad y navegabilidad. Considero que la mayoría, entre ellas yo, nunca imaginamos cuantos cambios se deben hacer, al principio del curso tan solo pensé que era agregar algunas herramientas y listo. Pero hay que revisar línea por línea el código, ahora entiendo porqué se debe tener en cuenta desde el inicio de nuestro proyecto. Me encantó el curso y desde la primera clase me mantuve a la expectativa. Desde hace años tuve la inquietud de reaizar una página accesible pero no sabía todo lo que se debía tener en cuenta y lo había olvidado. Super genial el curso.
Mi explicación a los números y funcionamiento del carrousel es:
Esta programado sumando y restando valores, para mostrar un contenido y sumar o resta dependiendo si se moverá a la izquierda o derecha.
El 0 es el inicial (Proyecto 1,2,3)
El -270 muestra Proyecto 2,3,4
El -540 muestra Proyecto 3,4,5
Cada que va la derecha resta y a la izquierda suma (Según veo en el JavaScript)
Excelente forma de ejecutarlo, tuve un pequeño bug al ejecutarlo y es que me estaba interceptando el elemento anterior, para eso agregue un options
let options ={root:document.querySelector('.window'),threshold:.80}...functionobserveElement(elements, behaviour){newIntersectionObserver(behaviour,options).observe(elements)}
Con esa configuración tomó como elemento principal al div con la clase window (declarado en el root) y que se observe con un mínimo de 80% ( threshold: .80)
Saludos.
Buen aporte! no lo he probado aún, pero entiendo que es realmente dinámico, a diferencia del switch para cada combinación (que debería ser actualizado cada vez que se incorpore una item).
Vale, he entendido el funcionamiento de tabindex. Pero pensándolo bien, si hacemos uso de él, ¿no estaríamos haciendo más complicada la navegación para los usuarios que utilizan un lector de pantallas?
.
Me explico:
.
Juliana nos recuerda que debemos intentar replicar la misma UX para todos nuestros usuarios, tanto si usan un **mouse **o un **lector de pantallas. **
.
En el caso del usuario promedio que utiliza un mouse, al momento de llegar al carrusel, tendrá que hacer clic en los botones para visualizar las demás imágenes dentro de este.
.
Si queremos replicar esa misma experiencia, el tener que hacer clic en los botones para deslizar el carrusel, para alguien que utiliza un lector de pantallas, ¿no sería mucho mejor que el carrusel mostrara las imágenes a medida que vas haciendo tab? como ya lo hace por defecto si no le agregamos el tabindex. Porque, creo que, al obligar al usuario de lector, a tener que hacer tab en los botones de forward y backward para mover el carrusel, sólo estamos estropeando su UX.
.
¿Qué piensan ustedes?
.
Yo le veo más utilidad al tab index, en un carrusel mucho más grande, donde, efectivamente no queremos que el usuario tenga que visualizar todas las imágenes. Pero en este caso, al ser sólo 5 imágenes lo considero innecesario.
Hola Gabriel :)
Pienso que, como Juliana lo indica, la idea es acercar la experiencia de un usuario que usa teclado a la del usuario que usa mouse.
Aunque entiendo completamente lo que indicas, pensaría que la navegación por el carousel a través del tab (llamémosle de forma "automática" y sin usar los botones) sería acertada si es que la navegación de un usuario del común que usa mouse, también se hace "automática", por ejemplo, al ubicar el mouse al extremo derecho (o izquierdo) del contenedor de las tarjetas.
En mi opinión, agregar botones ya hace que la persona piense que tendrá que usarlos, y si hacemos que la navegación por el carousel sea "automática" (únicamente a través del tab), se podría generar un efecto negativo sobre la persona que está usando el teclado y que no pudo hacer uso de dichos botones (porque su funcionalidad fue "automatizada").
En conclusión, me parece adecuado que tanto los usuarios de mouse como los usuarios de teclado, usen los botones para lo que fueron dispuestos.
P.D.: para no llenar tus aportes o preguntas de puntos(.) que simulen los saltos de línea, puedes usar backslash en cada línea que quieras dejar en blanco (\).
La idea es respetar los patrones de navegación del usuario. Forzar al usuario a usar tu sitio de una forma que no le es natural no es lo más recomendable. El usuario debería poder usar tu sitio de la forma en que SU herramienta funciona nativamente, esto significa que los botones accionan cosas, y eso es lo que espera el usuario, ya sabe que así es como funcionan los carruseles.
Imagina que a ti como usuario vidente te ponen un carrusel que se mueve presionando un botón que está en el footer. Bueno, ya te puedes dar una idea, de a donde quiero llegar. 😃
Creo que los temas del foco del teclado y cómo funcionan los lectores son bastante importantes tenerlos en cuenta para construir la mejor experiencia para los usuarios. Con esto en mente, yo no tenía muy calro cómo funcionaba así que me di a la tarea de probar con el lector y el navegador (en mi caso, screen reader de google chrome) como funcionaba esto y puedo extraer las siguientes conclusiones.
.
Disclaimer:
.
Los lectores no funcionan igual, encontré diferencias entre el lector de Windows y el de google chrome. Y no sé si le pasa a los demás, pero son un poco tediosos de usar, a veces los comandos funcionan y a veces no, al menos eso me pasó a mi.
.
Las pruebas que hice fueron principalmente con screen reader de google chrome
.
Conclusiones.
El lector del navegador tiene como dos formas de leer. Por una parte hace toda la lectura de la pagina incluyendo texto y titulos. Por otra parte hace la lectura a través de los elementos enfocables como botones, enlaces, etc.
.
Tabindex hace que un elemento sea enfocable por la navegación con el teclado, eso significa que se lo puedes agregar, por ejemplo, a un h2 y ahora, cuando estés navegando con el teclado podrás enfocar ese h2 y el lector lo leerá.
.
Sin embargo, el lector también leerá ese h2 si no tiene el tabindex colocado, lo leerá en su lectura normal como parte de la pagina, pero obviamente no podrás colocarle sobre él en la navegación con el teclado si no tiene el tab index.
.
Aria-label te permite agregarle una descripción a un elemento que normalemente no la tiene. Por ejemplo, puedes agregarle un arial-label a una <ul> para describir qué contiene esa <ul> y el lector leerá para el usuario esa descripción. Si no lo agregas, el lector le informará al usuario que es una <ul>, le dirá cuantos elementos tiene pero no habrá descripción de esa <ul>.
.
El lector leerá esas descripciones de arial-label en su modo de lectura normal de la pagina, pero si no le colocas un tabindex, no la leerá en el modo de navegación con el teclado
.
Con estas conclusiones en mente creo que algunas practicas que se pueden extraer son:
.
Darle descripciones a las secciones, listas y lo que consideres necesario para que el usuario sepa dónde está con arial-label
Por cómo funciona el lector, no se necesita hace enfocable con tabindex todos los elementos de la pagina.
El lector va a leer todo el contenido en su modo de lectura, incluyendo titulos, parrafos, elementos interactivos como botones.
También puedes navegar a través de los elementos que no tienen tabindex y que no son interactivos, al menos en screen reader es con la tecla "Insert" + las flechas. Es como la navegación con el teclado pero a través de todos los elementos y no solo los interactivos
.
.
Si tienen correcciones de esto o hay algo incorrecto, por favor respondan a este comentario
Lo logré
Me encanta la tipografía y los colores. Con los cambios de diseño que has incorporado, la página ha mejorado mucho. Excelente trabajo!
Accesibilidad - JS
Eliminar un elemento usando tabindex="-1"
setAttribute: Agrega un nuevo atributo.
remoteAttribute: Elimina un atributo
Alguna razón específica para que los números del switch sean esos?
Por lo que entiendo el carrousel esta programado sumando y restando valores, para mostrar un contenido y sumar o resta dependiendo si se moverá a la izquierda o derecha.
El 0 es el inicial (Proyecto 1,2,3)
El -270 muestra Proyecto 2,3,4
El -540 muestra Proyecto 3,4,5
Cada que va la derecha resta y a la izquierda suma (Según veo en el JavaScript)
es la posición en la que se encuentran y el - indica que se desplaza hacia la izquierda, cada item del carrusel con margenes y todo tiene un ancho width:270 px, cuando restas -270px quiere decir que desplazaste un item hacia la izquierda y con -540 es este que ya esta oculta mas otro que se desplaza hacia la izquierda. y se mostrarían en el carrusel de la siguiente forma:
Yo un poco también, creo que los que desde hace tiempo tienen conocimiento de programación llevan la ventaja.
Tenía el tabindex en el <li> y no entendía por qué, a pesar de que tenía el tabindex="-1" en el elemento que contiene a los demás elementos el lector seguía teniendolo en cuenta y enfocandolo.
.
Luego me di cuenta que es así porque el <li> no es enfocable mientras en <button> si es enfocable, esa en la razón por la que el lector seguía leyendo los botones 4 y 5 del carrusel a pesar de que yo tenia el tabindex="-1" en el elemento <li> que contenía ese <button>
Tab index <3
desde mi perspectiva se escribio un monton de codigo que al final hace menos accesibles los elementos del carrusel a un usuario con lector de pantalla
El switch dentro del JavaScript, solo mejora en este caso la navegación del carrusel por el teclado. La accesibilidad por mouse se mantiene
Resumen: Manejando el foco del teclado usando JavaScript
En esta clase se explica cómo hacer que un carrusel sea accesible para usuarios que navegan con teclado, usando el atributo tabindex y JavaScript.
Tabindex indica si un elemento puede recibir foco y si participa en la navegación secuencial con la tecla Tab.
Valores principales de tabindex:
tabindex="-1"
Permite enfocar el elemento solo de forma programática, pero lo excluye de la navegación con teclado.
Se usa para ocultar elementos que no están visibles, pero debe usarse con cuidado para no romper la igualdad de interacción.
tabindex="0"
El elemento es enfocable y sigue el orden natural del HTML. Es el valor más seguro y recomendado.
Valores positivos (tabindex="1", 2, etc.)
Definen un orden manual de navegación. Se desaconseja su uso en sitios grandes porque puede romper la navegación si no se mantiene correctamente.
Aplicación en el carrusel
Se trabaja principalmente con botones, ya que son elementos que reciben foco por defecto.
A los proyectos que no están visibles se les asigna tabindex="-1" para ocultarlos de la navegación por teclado.
A los proyectos visibles se les elimina el atributo tabindex, permitiendo que sean accesibles nuevamente.
Se asignan clases a los botones (proyecto 1, 2, 3, etc.) para controlarlos desde JavaScript.
Uso de JavaScript
Se usan event listeners en los botones de navegación (derecha e izquierda).
Dentro de las funciones se implementa un switch que, según el estado del carrusel, cambia qué proyectos:
reciben tabindex="-1" (se esconden)
o tienen el atributo removido (se hacen accesibles)
El mismo manejo se replica tanto para avanzar como para retroceder en el carrusel.
Resultado
El carrusel puede recorrerse con el teclado de la misma forma que con el mouse, manteniendo una experiencia consistente y accesible para todos los usuarios.
Entiendo que la intención es que la navegación sea igual en teclado y mouse, pero no lo estamos haciendo más complicado en teclado ? No sería más facil para un persona con teclado navegar directamente entre todos los elementos con el Tab, y no ponerla a deslizar el slider cada 3 elementos ?
Seguramente cada proyecto será un enlace que mande a un sitio web donde podamos ver qué era el proyecto en sí. Aquí son puras imágenes pero es con fines didácticos. Además recuerda que podemos ver con más zoom cada proyecto. Entonces me parece bien que se quede así.
Una forma mas optima de hacer esto, es crear dos obetos para cada boton que contengan las funciones que va a realizar en cada caso:
Asi, luego en cada funcion solo mandamos a llamar el objeto con su propiedad de acuerdo al valor que guarde la variable newValue y como sabemos que nos devolvera una funcion, la ejecutamos, de este modo:
En la funcion clickRight: valuesRight[`${newValue}`]();
En la funcion clickLeft: valuesLeft[`${newValue}`]();
No es recomendable utilizar tabindex > 0 ya que podría ser difícil ara el usuario saber cual elemento será el siguiente. Podría asignarse a cada uno de los elementos de la pagina en el orden deseado pero no seria mantenible. La mejor practica es tener siempre tab index 0 y que sigan el orden lógico de la pagina y usar el -1 para aquellos que no se muestran visualmente
Si no les funciona, revisen en qué función están metiendo el switch; me pasó que la primera se la puse al clickLeft y la segunda no hallaba dónde meterla, entonces me perdí un poco.