Primero sería Firefox 98, en marzo de este año, quien se sumaría a darle soporte1, y Safari haría lo propio al poco tiempo con su más reciente versión, la 15.42, pasando así el elemento <dialog>
de HTML5 a ser soportado por todos los navegadores modernos3.
Especificaciones principales
Categoría a la que pertenece: Contenido de flujo4, seccionado raíz5.
Contenido permitido: Contenido de flujo.
Interfaz de DOM:
HTMLDialogElement
.
Contexto de uso
Se usa para representar un cuadro de diálogo o ventana modal, ya sea para informar algo importante al usuario, como para involucrarlo en alguna acción o toma de decisiones. Están inspirados en los que vemos comúnmente en todos los sistemas operativos.
Problemas que resuelve
Las soluciones mágicas que nos trae, además de tener un impacto positivo del lado del usuario, mejoran también la experiencia de desarrollo. Veamos algunas.
Accesibilidad y experiencia de usuario
El diálogo se cierra al presionar la tecla Esc, interacción que cualquier usuario, tenga una discapacidad o no, agradecerá siempre.
Por defecto, el foco se coloca automáticamente sobre el primer elemento enfocable que exista dentro, a no ser que se indique otro explícitamente usando el atributo autofocus
.
Al cerrarse el diálogo, el foco vuelve a donde se encontraba antes (típicamente el botón o elemento que disparó su apertura).
Por otro lado, para que las tecnologías de apoyo, como los lectores de pantalla, comuniquen al usuario el propósito del diálogo, es suficiente con usar aria-labelledby
en el elemento, apuntando al id
del título del mismo, o sumistrar el texto directamente mediante aria-label
. Si este no fuese lo suficientemente descriptivo, se puede recurrir a aria-describedby
6.
<dialog aria-labelledby="dialog-title">
<h1 id="dialog-title">Agregar a la billetera</h1>
...
</dialog>
<dialog aria-label="Agregar a la billetera">
...
</dialog>
De esta forma, al abrirse el diálogo, se anunciará su título seguido de la palabra "diálogo" (si no se provee, se anuncia solamente "diálogo"). Además, huelga decir que ya nos podemos olvidar del uso de role="dialog"
, ya que, al ser una etiqueta semántica, su rol es implícito, pudiendo únicamente cambiarse por el más específico role="alertdialog"
7 8.
Interacción y estilos
Invocando el método show()
del elemento, se muestra el diálogo sin impedir la navegación por el resto del documento, mientras que showModal()
confina al usuario, realizando focus trap, hasta tanto se ejecute el método close()
; al accionarse un botón, por ejemplo, o si se pulsa Esc. Además, showModal()
agrega una capa de overlay para ocultar el contenido subyacente, la cual puede ser accedida por CSS para su personalización, mediante el pseudoelemento ::backdrop9.
Si se busca conocer el estado (abierto o cerrado) del diálogo, se puede consultar el atributo (implícito) open
del elemento, el cual retorna un booleano. Una advertencia: ¡nunca se debería modificar el valor de este atributo o removerlo! En primer lugar, porque el navegador perdería por completo el rastro del estado, produciendo varios efectos no deseados10; y en segundo lugar, ¿por qué querrías hacerlo, si al final se controla "automágicamente"?
Conclusiones
A estas alturas, y si eres alguien con ciertos conocimientos de accesibilidad, te resultarán más que evidentes las ventajas que trae de serie este elemento. Hasta ahora, debíamos tener una serie de consideraciones que, si se descuidaban, fácilmente nuestras modales podían volverse una pesadilla para la accesibilidad. Otra opción era buscar una librería que proporcione diálogos accesibles, a cambio de ceder el control sobre nuestro markup, o terminar invirtiendo en personalización el tiempo que se pretendió ahorrar en un principio.
En cualquier caso, había que cerciorarse de que se cumpla con lo siguiente:
- Indicar el rol: para que las tecnologías de apoyo puedan anunciar que se trata de un diálogo.
- Atrapar el foco -aplica para ventanas modales-: Se trata, hoy por hoy, de una labor prácticamente artesanal, y consiste en hacer que, al avanzar el foco con la tecla tabuladora (Tab), tras haber alcanzado el último elemento interactivo del diálogo, este vuelva a posarse sobre el primero; y a la inversa, al retroceder con Shift + Tab, impidiendo que el usuario navegue a otras partes del documento por fuera de la ventana modal.
-
Bloquear el resto del documento: por la misma razón que en el caso anterior: en una ventana modal, queremos que el usuario se concentre en una acción específica. Para esto, la práctica más común es volver el resto del contenido invisible para los usuarios de tecnologías de asistencia cuando la modal está visible, añadiendo
aria-hidden="true"
mediante JS a un contenedor principal, colocando por fuera al elemento que hace las veces de diálogo; además, conviene agregar a este último el atributoaria-modal="true"
, de esa forma los productos de apoyo avisarán que el resto del contenido está inactivo. Luego, hay que recordar cambiar aaria-hidden="false"
o remover el atributo por completo del nodo cuando la modal se cierre. - Controlar el estado abierto/cerrado: para impedir la creación de diálogos duplicados o permitir volver a abrir un diálogo cerrado; para lo mencionado en el punto anterior sobre el bloqueo del documento.
- Conservar la referencia del elemento que abrió el diálogo: para devolver el foco a su sitio original al cerrarlo.
Probablemente nos hayamos encontrado realizando estas tareas de manera repetitiva en el pasado. Bueno, se podría decir que ya no tendremos que preocuparnos más por ellas.
Sin embargo, como sucede con toda nueva característica, conviene que sea usada con prudencia y proporcionando algún tipo de fallback para agentes de usuario más antiguos: versiones de navegadores aun vivas o tecnologías de apoyo cuyo ciclo de actualización es más lento. Una buena opción, bastante robusta, puede ser a11y-dialog. También existe un polyfill publicado por el equipo de Chrome. No nos olvidemos que la retrocompatibilidad también forma parte de la accesibilidad.
Top comments (0)