Contenido:

Aprende a crear modales sin usar z-index con el elemento dialog

En el pasado, se utilizaban diversas técnicas para crear modales, pero todas presentaban ciertos problemas. Uno de los más comunes era la superposición de elementos, lo que obligaba a recurrir a valores exagerados en la propiedad z-index, como z-index: 99999. Seguramente, en algún momento te has encontrado con este tipo de inconveniente en una página web.

Aunque existen librerías que facilitan la creación de ventanas modales, encontrar una que realmente se adapte a nuestras necesidades puede ser complicado, especialmente cuando queremos que el modal mantenga la apariencia y el estilo de nuestro sitio. Esto se debe a que la mayoría de las librerías incluyen estilos predeterminados que algunas veces no son fáciles de personalizar.

Ahora, gracias al Elemento HTML <dialog>, crear ventanas modales es mucho más sencillo. Es posible hacerlo con muy poco JavaScript, con total control sobre el diseño y sin tener que preocuparse por la propiedad z-index ni por valores excesivos. En este post, te enseñaré todo lo que necesitas saber para crear modales con el elemento <dialog>, incluyendo cómo funciona, cómo se utiliza y cómo aprovechar al máximo sus ventajas.

¿Qué es el Elemento HTML Dialog?

El Elemento HTML <dialog> es una etiqueta introducida en HTML5 que facilita la creación de ventanas modales en una página web. La idea detrás del elemento <dialog> es ofrecer una forma sencilla y estandarizada de crear modales que se integren naturalmente con el resto de la página y que sean accesibles para todos los usuarios, sin importar su dispositivo o navegador.

Dado que los modales son un patrón de interfaz de usuario (UI) muy común, se decidió crear una API nativa que los desarrolladores web puedan utilizar fácilmente, sin depender de librerías de terceros que podrían afectar el rendimiento o la experiencia del usuario en un sitio web.

El elemento HTML <dialog> cuenta con soporte en la mayoría de los navegadores modernos:

Soporte del Elemento Dialog en los principales navegadores modernos - Mobile Soporte del Elemento Dialog en los principales navegadores modernos - Desktop

Puedes ver los datos más actualizados de soporte en los diferentes navegadores, en el siguiente enlace: https://caniuse.com/dialog.

¿Cómo funciona el Elemento HTML Dialog?

Este funciona gracias a top-layer o capa superior.

¿Qué es top-layer?

top-layer es una capa especial que se encuentra fuera del flujo natural del DOM. Los elementos que se renderizan dentro de esta capa no necesitan utilizar la propiedad z-index para superponerse a otros. Cualquiera dentro de top-layer aparecerá por encima de los demás, incluso si estos tienen un z-index muy alto.

El elemento HTML <dialog> no es el único que el navegador representa en la top-layer. Actualmente, también forman parte de esta capa los elementos que utilizan la Popover API (aún experimental) y los elementos en modo de pantalla completa mediante la Fullscreen API.

top-layer en un sitio web

Si deseas conocer más sobre top-layer, puedes darle un vistazo a este post de Chrome Developers: https://developer.chrome.com/blog/what-is-the-top-layer/.

Creando un modal con el Elemento Dialog

Para crear un modal con el elemento <dialog>, solo es necesario seguir unos sencillos pasos:

  1. Crea una etiqueta <dialog> en el código HTML e incluye dentro su contenido.
  2. Define los estilos y el comportamiento del cuadro de diálogo utilizando CSS y JavaScript, respectivamente.
  3. Muestra el cuadro de diálogo mediante JavaScript cuando sea necesario.

Veamos un ejemplo de cómo crear un modal con el elemento <dialog>:

index.html
<dialog>
<p>Este es mi modal</p>
<button class="close">Ok</button>
</dialog>
<button class="open">Mostrar modal</button>
<script src="./script.js"></script>
script.js
const buttonOpen = document.querySelector('.open');
const buttonClose = document.querySelector('.close');
const dialog = document.querySelector('dialog');
buttonOpen.addEventListener('click', () => {
dialog.showModal();
});
buttonClose.addEventListener('click', () => {
dialog.close();
});
Vista previa

En este ejemplo, hemos creado un elemento <dialog> que actúa como ventana modal. Dentro del cuadro de diálogo incluimos un párrafo y un botón. Luego, añadimos un segundo botón fuera del modal que lo activa al hacer clic. Para mostrar el cuadro de diálogo, utilizamos el método .showModal() de la API HTMLDialogElement.

Diferencias entre el método show y showModal

Para abrir un modal con JavaScript, existen dos métodos que podemos utilizar: .show() y .showModal(). La elección entre uno u otro presenta diferencias importantes.

Al utilizar el método .show(), el contenido que se encuentra detrás del modal sigue siendo accesible y puede seleccionarse. En cambio, al usar el método .showModal(), el contenido de fondo queda aislado e inaccesible, lo que hace que el modal sea el elemento más destacado mientras está abierto. Por esta razón, se recomienda utilizar .showModal() cuando se desea un comportamiento de modal tradicional.

Ejemplo utilizando el método .show():

Vista previa

Ejemplo con el método .showModal():

Vista previa

Añadiendo animaciones al Elemento Dialog

Como habrás notado, el elemento <dialog> no incluye animaciones por defecto. Sin embargo, con unas pequeñas modificaciones en CSS y JavaScript podemos agregar efectos de apertura y cierre para hacerlo más dinámico. Veamos algunos ejemplos.

Hacer que el modal se traslade

En el primer ejemplo, haremos que nuestro modal se desplace de arriba hacia abajo al abrirse y en sentido contrario al cerrarse.

Comencemos con el HTML y definamos la estructura básica de nuestro modal:

index.html
<dialog>
<p>Este es mi modal</p>
<button class="close">Ok</button>
</dialog>
<button class="open">Mostrar modal</button>

Ahora vamos a aplicar estilos a nuestro modal para que pueda desplazarse:

styles.css
dialog[open] {
animation: show 1s ease normal;
}
dialog.hide {
animation: hide 1s ease normal;
}
@keyframes show {
from {
transform: translateY(-200%);
}
to {
transform: translateY(0%);
}
}
@keyframes hide {
to {
transform: translateY(-200%);
}
}

Creamos dos @keyframes: uno llamado show, que desplazará nuestro modal desde fuera del viewport en la parte superior hacia abajo; y otro llamado hide, que simplemente deslizará el modal hacia arriba y fuera del viewport al cerrarse.

A continuación, añadimos funcionalidad a nuestro modal con JavaScript:

script.js
const buttonOpen = document.querySelector('.open');
const buttonClose = document.querySelector('.close');
const dialog = document.querySelector('dialog');
buttonOpen.addEventListener('click', () => {
dialog.showModal();
});
buttonClose.addEventListener('click', () => {
dialog.classList.add('hide');
dialog.addEventListener('animationend', function close() {
dialog.classList.remove('hide');
dialog.close();
dialog.removeEventListener('animationend', close);
});
});

En sencillos pasos, al cerrar el modal, el código JavaScript funciona de la siguiente manera:

  1. Al hacer clic en el botón de cerrar, se agrega la clase .hide.
  2. Se establece un listener animationend en el modal (esto corresponde al @keyframes de la clase .hide). Es importante que el callback sea una función nombrada, ya que la necesitaremos más adelante.
  3. Cuando la animación del modal finaliza, se elimina la clase .hide.
  4. Se cierra el modal utilizando el método .close().
  5. Se elimina el listener animationend del modal, pasando nuevamente la función nombrada, para evitar que la animación se ejecute en un bucle.

Así es como se ve nuestro modal en acción:

Vista previa

Efecto de escala (scale)

Ahora haremos que nuestro modal se expanda al abrirse y se encoja al cerrarse. Podemos reutilizar el mismo código HTML y JavaScript del ejemplo anterior, modificando únicamente los estilos CSS.

Para ello, utilizamos la función de CSS scale():

styles.css
dialog[open] {
animation: show 1s ease normal;
}
dialog.hide {
animation: hide 1s ease normal;
}
@keyframes show {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
@keyframes hide {
to {
transform: scale(0);
}
}
Vista previa

Utilizando el pseudo-elemento ::backdrop

Una de las ventajas del elemento <dialog> es que permite usar el pseudo-elemento ::backdrop para aplicar estilos al fondo de la top-layer mientras se muestra el cuadro de diálogo. Esto ayuda a que el modal sea más visible y destacado dentro de la página.

Veamos un ejemplo de cómo utilizar el pseudo-elemento ::backdrop:

styles.css
dialog::backdrop {
backdrop-filter: blur(4px);
background-color: rgba(0, 0, 0, 0.5);
}

En este ejemplo, aplicamos un efecto de desenfoque al fondo de la página web utilizando la propiedad CSS backdrop-filter. Además, se agregó un color de fondo semitransparente mediante la propiedad background-color.

El resultado se vería así:

Vista previa

Ventajas del Elemento <dialog>

El elemento <dialog> ofrece varias ventajas frente a las técnicas tradicionales para crear modales en una página web:

Polyfill para navegadores antiguos

Aunque el elemento <dialog> es compatible con los principales navegadores modernos, su soporte en Safari es relativamente reciente. Por esta razón, en versiones antiguas del navegador (anteriores a la 15.4, tanto en móvil como en escritorio) es necesario utilizar un polyfill para habilitar la funcionalidad del <dialog>.

Para ello, se puede emplear el polyfill dialog-polyfill, que ofrece una implementación completa del elemento <dialog> en navegadores que no lo soportan de forma nativa.

Veamos un ejemplo de cómo utilizar el polyfill dialog-polyfill:

index.html
<!DOCTYPE html>
<html lang="es">
<head>
<link rel="stylesheet" type="text/css" href="dist/dialog-polyfill.css" />
<script src="dialog-polyfill.js" defer></script>
</head>
<body>
<dialog>
<p>Este es mi modal</p>
<button class="close">Ok</button>
</dialog>
<button class="open">Mostrar modal</button>
<script>
const buttonOpen = document.querySelector('.open');
const buttonClose = document.querySelector('.close');
const dialog = document.querySelector('dialog');
if (!('showModal' in document.createElement('dialog'))) {
dialogPolyfill.registerDialog(dialog)
buttonOpen.addEventListener('click', () => {
dialog.showModal();
});
buttonClose.addEventListener('click', () => {
dialog.close();
});
}
</script>
</body>
</html>

Y eso es todo. Ahora, al probar tu página en navegadores donde el elemento <dialog> no está soportado, verás que funciona de la misma manera que en los navegadores modernos.

Si quieres aprender más sobre el polyfill, puedes visitar su repositorio en GitHub: https://github.com/GoogleChrome/dialog-polyfill.

Conclusión

El elemento HTML <dialog> es una característica de HTML5 que permite crear ventanas modales en una página web de manera sencilla y accesible. Con <dialog> es posible implementar modales sin depender de la propiedad CSS z-index, lo que facilita su integración con el resto del contenido y mejora la accesibilidad para todos los usuarios.

Para utilizar <dialog>, basta con crear un elemento <dialog> en el HTML y emplear las funciones .showModal() y .close() en JavaScript para mostrar y ocultar el modal. Además, se puede usar el pseudo-elemento ::backdrop para personalizar la apariencia del fondo mientras el modal está activo.

Aunque <dialog> es compatible con la mayoría de los navegadores modernos, es posible utilizar un polyfill como dialog-polyfill para habilitar su funcionalidad en navegadores antiguos.

En resumen, el elemento HTML <dialog> es una herramienta práctica y accesible para crear modales en la web. Su fácil integración, personalización y compatibilidad con la mayoría de los navegadores lo convierten en una opción ideal para desarrolladores que buscan implementar modales de forma sencilla y estándar en sus proyectos.

Otros artículos

Optimizar la Carga de Imágenes en tu Sitio Web con Placeholders

Conoce todas las Técnicas de Renderizado de Sitios Web

¿Qué son las Progressive Web Apps?

Dark Mode: Buenas Prácticas para Crear un Modo Oscuro Efectivo

Core Web Vitals: Las Métricas de Optimización Web

Efecto Hover: Aprende a usarlo correctamente en tus estilos CSS