Oriol

Circles Game for iOS

Los artículos sin foco

Hace un tiempo estuve enredado con una web donde teníamos una serie de artículos al que el usuario podía acceder mediante enlaces, típico de las webs de noticias. La idea era que el artículo hiciera su aparición estelar tipo SPA, sin que cambiase la URL ni el título de la página (otro fallo de accesibilidad, quedarse con el título de la página principal en toda la app).

A alguien se le encendió la lucecita y en producción, al hacer la auditoría, me topé con algo así:

<a onclick="showArticle(id)" title="noticia de última hora">noticia de última hora</a>

Pero aquí está el problema del plan, los enlaces eran como fantasmas de teclado: cualquier enlace que no tenga atributo href, pierde el foco del teclado y su funcionalidad con la tecla Enter. Es decir, si el usuario va tabulando, se saltaba la sección entera de noticias. Además, cuando se trata de webs con contenido similar, por ejemplo una secuencia de artículos, se suele envolver cada enlace a contenido con un encabezado para que la navegación sea más fluida.

Pero espera... No quiero poner href, qué hago?

  • Añade el atributo tabindex a los enlaces para que puedan recibir enfoque y maneja el evento Enter utilizando JavaScript.
  • Convierte el enlace en un botón utilizando el elemento button con el rol adecuado (link o tab) según el contexto de la página.

Es también importante que el usuario se entere de que se ha cargado el artículo. En esa web en particular, el artículo aparecía arriba del todo de la página sin enfocarse. Eso significa que cualquier usuario sin visión que utilice lector de pantalla, ni se va a dar cuenta de que ha aparecido el artículo por arte de magia. Para evitar eso, asigna tabindex -1 al encabezado del artículo (sí, hay que meter un encabezado también!) y llama a la función focus() una vez esté cargado. de esta manera, le ahorras al usuario tener que desplazarse arriba a la vez que le indicas que el artículo se ha cargado.

Conclusión

Si vas a hacer un enlace, haz un enlace. Esto significa que es esencial respetar la semántica y las funcionalidades nativas de HTML para asegurar una experiencia accesible y optimizada para todos los usuarios. No me vale que uses un enlace por el truquito visual y que luego no le des la funcionalidad que merece.

El curioso caso de Pressed Button

Con este encabezado, cuyo título tiene bastante parecido a cierta película bastante buena, quiero presentaros otro caso que estoy viendo últimamente muchas veces en páginas webs de transmisión de audio y vídeo. atención a este código:

    <button id="muteButton" aria-pressed="false" onclick="toggleMicrophoneState()">Silenciar el micrófono</button>
        function toggleMicrophoneState() {
            var button = document.getElementById('muteButton');
            let isPressed = button.getAttribute('aria-pressed') == 'true';
            isPressed = !isPressed;

            // Cambia el estado de aria-pressed
            button.setAttribute('aria-pressed', isPressed);

            // Cambia el texto del botón
            if (isPressed) {
                button.textContent = 'Reactivar el Micrófono';
            } else {
                button.textContent = 'Silenciar el Micrófono';
            }
        }

A priori es una idea bastante chula. qué guay, le estoy diciendo al usuario de lector de pantalla que el botón, cuando está pulsado, significa que el micro está muteado y que si hace click lo volverá a desactivar. Vamos a cambiar el texto del botón también, para que así haya menos confusión aún, para que quede bien claro. ¿No?

Bien, presta atención a lo que dice NVDA cuando el usuario pasa por encima de este botón:

Silenciar el Micrófono  botón conmutador  sin pulsar  

Hasta ahí bien. Nos está diciendo que el micrófono está silenciado. Si lo pulso, el botón estará pulsado y ya está, ¿no?

Reactivar el Micrófono  botón conmutador  pulsado

vamos a desgranar esto. Por un lado nos está diciendo que tenemos un botón, que se llama Reactivar Micrófono, y que está pulsado. ¿Eso significa que el micrófono está activado o que está silenciado y que el botón está pulsado. ¿Tengo el micro encendido o apagado?

Incluso en Google Meet lo hacen un poquito mal (a estos sí que no me importa mencionarlos, ahora veréis por qué digo que solo lo hacen un poquito mal). Cuando estamos en una llamada de Google Meet, tenemos lo siguiente.

Desactivar micrófono  botón conmutador  sin pulsar  
intro
Tu micrófono está desactivado. 
Activar micrófono  botón conmutador  pulsado  
intro
Tu micrófono está activado. 
Desactivar micrófono  botón conmutador  sin pulsar  
`` 

Esto es de los comportamientos más liosos que me he encontrado. Por un lado, está guay que creen una región dinámica que anuncie el estado del micro y que haya un acceso directo (Control + D) para cambiar el estado del micro rápidamente. ¿Pero realmente hacía falta que ese botón cambiara su texto de forma dinámica?

Mi opinión es que no. Tan solo con añadir el texto silenciar Micrófono, y cambiando su atributo aria-pressed de true a false, tendríamos una experiencia mucho más fluida, algo así como:

```sr
Silenciar micrófono botón conmutador  sin pulsar

Quiero mutear el micrófono y le doy al espacio...

Silenciar el Micrófono botón conmutador  pulsado

De esta manera, es mucho más sencillo para el usuario saber si el micrófono está silenciado o no, sin tener que recurrir a preguntar si se le escucha o fijarse en una región dinámica (que no todas las plataformas de transmisión tienen).

Este mismo comportamiento me lo he encontrado en multitud de páginas webs y en multitud de acciones, por ejemplo:

  • Añadir a favoritos sin pulsar, eliminar de favoritos pulsado;
  • Desactivar la cámara sin pulsar, activar la cámara pulsado.

Haciendo el código para este ejemplo me he liado hasta yo. Me han hecho falta 3 o 4 iteraciones para ver cuándo tenía que poner silenciar y cuándo reactivar, para que veáis lo curioso de la situación.

Conclusión sobre este caso

No te líes, y haz pruebas. Si eres desarrollador y te han mandado programar esto, asegúrate de que haces pruebas con la persona de tu empresa que se encarga de la accesibilidad. Enseguida se dará cuenta de que el comportamiento es extraño. Todos cometemos errores, y este es uno muy fácil de cometer. Pero por favor, no lo subas a producción.

El cuadro de edición que abre diálogo y el foco que desapareció

Hace un tiempo estuve trabajando con un equipo de desarrolladores en un design system. Nos tocaba modificar un componente de calendario típico, donde el usuario podía hacer click sobre un campo de texto para ingresar una fecha, y al hacerlo, se desplegaría un modal con un selector de día, mes y año.

La idea, de primeras, parecía bastante sencilla. Yo acababa de entrar en el proyecto y no había visto los diseños que se habían hecho para este componente ni tampoco la documentación de accesibilidad, por lo que me dí de lleno con la página del componente en su Storybook. Agárrate los pantalones porque se viene idea revolucionaria:

cuando el usuario pulsaba la tecla Enter estando en el campo de edición, se abriría automáticamente un cuadro de diálogo para la selección de fechas. En código, sería algo así:

    <label for="dateInput">Seleccionar Fecha</label>
    <input type="text" id="dateInput" aria-haspopup="dialog" aria-expanded="false" aria-controls="dialogBox" />
    <div id="dialogBox" role="dialog"...></div>

Para empezar, utilizar aria-haspopup y aria-expanded en un campo de edición resultaba, cuanto menos, inusual. Pero más allá de eso, la verdadera complicación radicaba en que al presionar Enter, el diálogo no se enfocaba correctamente. A parte de que te estás comiendo el comportamiento de la tecla enter, estás haciendo que el usuario no se entere de que se ha abierto el selector.

Cuando vi esto me puse a flipar en colores, y eso que soy ciego total y no he visto colores en la vida. Propuse entonces, pensando en la idea de los skip links (enlaces que solo se visualizan con el foco de teclado) crear un botón al lado del cuadro de edición para que el usuario de teclado (atención, teclado, no lector de pantalla) pueda pulsar enter y espacio para que se abra el cuadro de diálogo con el selector de fechas.

A priori era una idea guay, y pensando en posibles confusiones, intenté dejar claro con código CSS que el botón de seleccionar fecha debe ser visible siempre que el usuario tenga el foco de teclado ahí. Mi ejemplo era algo parecido a lo siguiente:

<button class="select-date" aria-haspopup="Dialog" aria-label="Seleccionar Fecha" aria-expanded="true/false"> <svg del iconito del calendario que UX había creado/> </button>
.select-date {
  position: absolute;
  top: -40px; /* no se ve */
  left: 10px;
  background-color: #0073e6;
  color: white;
  padding: 8px 16px;
  transition: top 0.3s;
  text-decoration: none;
}

.select-date:focus {
  top: 10px; /* Lo pone en pantalla */
}

Esto estaba genial, de hecho cuando llegó la nueva revisión del componente mi intención era aprobarlo con un “wow, qué chulo!” han hecho un selector de fecha súper accesible y ahora el usuario de teclado ya no se va a perder. Pero esperaos un momento, que voy a consultarlo con mi compañero de visual, a ver que no sea que se rompa la UI o algo.

Cuál fue mi sorpresa cuando mi compañero me dijo que habían pasado de mi código de ejemplo. Cuando el usuario estaba en el cuadro de edición, todo guay, pero al hacer tab, el foco de teclado se iba al limbo perdido, más allá de los confines del espacio interestelar. el lector de pantalla, sin embargo y correctamente, anunciaba que el foco estaba en el botón Seleccionar Fecha.

Hablando con los compañeros desarrolladores, se ve que habían asumido que ese botón era invisible. Total, para qué vas a poner que se vea el botón, si es un usuario de teclado y lector de pantalla?

Ahí está el quid de la cuestión, alguien se había tomado la libertad de asumir que un usuario de teclado es usuario de lector de pantalla siempre, y ese ese es el error que nunca debemos cometer. Usuarios de teclado pueden ser muchos y muy variados, desde personas que tienen poca movilidad en la mano y no pueden usar el ratón, personas con baja visión, personas que utilicen dispositivos de control alternativos...

Conclusión sobre este caso

Hay que leer la documentación que te han dado. Si eres desarrollador y no sabes mucho de accesibilidad o estás aprendiendo, si te ponen un ejemplo para un botón que aparece visualmente con el foco, no pases. Tampoco hagas un cuadro de edición con un haspopup y un expanded, por favor.

Me llamo Oriol Gómez Sentís y durante los últimos cuatro años estoy inmerso en el mundo de la accesibilidad web. Un detalle crucial sobre mi experiencia es que soy ciego total, un aspecto que tendrá un papel bastante significativo en los casos que desarrollaré a lo largo de este libro. Normalmente, en la mayoría de empresas o consultorías, la evaluación de la accesibilidad web se lleva a cabo con la ayuda de personas que emplean lectores de pantalla, quienes se enfocan principalmente en pruebas relacionadas con el uso del teclado y los propios lectores, además de pruebas de accesibilidad relacionadas a otros aspectos menos visuales. Además, existen consultores especializados que se encargan de realizar análisis visuales, que nunca hay que dejar atrás como el color, contrastes, foco de teclado, etc.

Digo que es importante el hecho de que soy ciego total porque en algunos de los casos, como el que viene a continuación, la ceguera jugará un papel importante sobre el problema que nos ocupa.

En un mundo cada vez más interconectado y donde las leyes sobre la accesibilidad parece que van tomando fuerza, la accesibilidad web se ha convertido en un componente esencial del diseño y desarrollo de sitios web. “Cómo crear contenido digital accesible sin ser un peligro” es una guía práctica diseñada para ayudar a desarrolladores, diseñadores y gestores de contenido a crear experiencias web inclusivas y accesibles para todas las personas sin cometer errores fáciles de cometer por desconocimiento.

Este libro nace de la creciente necesidad de entender la accesibilidad desde un punto de vista técnico. No estoy aquí para hablarte de los últimos avances en leyes y normas en Estados Unidos y la Unión Europea, o para enseñarte a hacer menús desplegables que funcionen bien con el teclado. Ya hay muchos libros sobre eso. Con esta pequeña guía, quiero contarte qué es lo que no hay que hacer. Es un compendio de algunos de los errores más apabullantes en páginas web o aplicaciones que he encontrado en proyectos y empresas donde he trabajado o contenido digital con el que me he topado como usuario.

A lo largo de este libro, veremos algunos de los errores más enrevesados cometidos en materia de accesibilidad, por supuesto sin citar fuentes. No es mi intención ridiculizar a nadie. La idea es que este libro sirva de guía educativa para evitar cometer las mismas atrocidades, con un poco de humor negro que quienes me conocen, saben que a veces me caracteriza, proporcionando ejemplos prácticos y consejos accionables. Quiero que dispongas de las herramientas necesarias para que puedas desarollar páginas webs accesibles sin que se rían de ti.

Prepárate para descubrir cómo no hacer skip links que hacen que el foco de teclado desaparezca y qué es lo que has hecho mal para que el aria-label que acabas de poner en tu web aparezca en Mastodon de lo inútil o malo que es.