+(505) 5727-9567¡Envíame un mensaje! contacto@felixicaza.com¡Envíame un correo electrónico!

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

21 Febrero, 2023

6 minutos de lectura

Contenido:

En el pasado, se utilizaban diversas técnicas para crear modales, pero todas ellas presentaban problemas, como por ejemplo que unos elementos se superponen con otros, por lo que se tenía que recurrir a utilizar z-index como: z-index: 99999, lo cual no es para nada útil, seguramente habrás tenido que lidiar con el problema de superposición en una página web.

Si bien hay librerías que nos facilitan la creación de ventanas modales, es muy difícil encontrar y elegir alguna que se ajuste a nuestras necesidades, especialmente cuándo dicho modal queremos que luzca como la guía de estilo de nuestro sitio, debido a que la mayoría ya incluyen estilos por defecto.

Ahora, gracias al Elemento HTML Dialoges mucho más fácil crear ventanas modales con muy poco JavaScript, personalizar completamente el estilo del modal y sin tener que lidiar con la propiedad z-index y con valores exagerados. 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 puedes aprovechar sus ventajas.

¿Qué es el Elemento HTML Dialog?

El Elemento HTML Dialog, es una etiqueta de HTML 5 que nos ayudará y facilitará con la creación de ventanas modales en una página web. La idea detrás del Elemento Dialog es proporcionar una forma sencilla y estándar de crear modales que se integren con el resto de la página y que sean accesibles para todos los usuarios, independientemente de su dispositivo o navegador.

Debido a que es un patrón de UI (Interfaz de Usuario) muy común, se decidió crear un API para que los desarrolladores web puedan utilizar de manera fácil, sin depender de librerías de terceros que podrían entorpecer la experiencia de los usuarios en nuestro sitio web.

El Elemento HTML Dialog está soportado por los principales navegadores modernos:

El Elemento Dialog está soportado por todos los navegadores modernos

El Elemento Dialog está soportado por todos los navegadores modernos.

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 Dialog?

El Elemento HTML Dialog funciona gracias a top-layero capa superior.

¿Qué es top-layer?

top-layer es una capa especial, que está fuera del flujo natural del DOM por lo que los elementos que estén dentro de esta capa no necesitan utilizar el z-index para sobreponerse sobre los demás. Un elemento dentro de top-layer aparecerá encima de un elemento incluso con el z-index más alto.

El Elemento HTML Dialog no es el único elemento que el navegador representa en top-layer. Actualmente, los elementos en top-layer son: Elementos utilizando la Popover API(aún experimental) y elementos en modo de pantalla completa utilizando la Fullscreen API.

Ejemplo de top-layer cuándo el Elemento Dialog está abierto

Ejemplo de top-layer cuándo el Elemento Dialog está abierto.

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, hay que seguir unos sencillos pasos:

  1. Primero, se crea una etiqueta <dialog> en el código HTML con su contenido dentro.
  2. A continuación, se establecen las opciones de estilo y comportamiento para el cuadro de diálogo mediante CSS y JavaScript respectivamente.
  3. Se activa el cuadro de diálogo mediante JavaScript cuando sea necesario.

Veamos un ejemplo de cómo crear un modal con el Elemento Dialog:

<dialog id="modal">
  <p>Este es mi modal</p>
  <button id="btn-close">Ok</button>
</dialog>

<button id="btn">Mostrar modal</button>

<script>
  const modal = document.querySelector('#modal')
  const btn = document.querySelector('#btn')
  const btnClose = document.querySelector('#btn-close')

  btn.addEventListener('click', () => {
    modal.showModal()
  })

  btnClose.addEventListener('click', () => {
    modal.close()
  })
</script>

En este ejemplo, hemos creado un Elemento Dialog con la etiqueta <dialog>. Dentro del cuadro de diálogo, se ha incluido un párrafo y un botón. A continuación, añadimos un botón que activa el cuadro de diálogo cuando se hace clic en él. Para activar el cuadro de diálogo, utilizamos el método .showModal() del objeto dialog.

Diferencias entre el método show y showModal

Para abrir un modal con JavaScript, existen dos métodos que podemos utilizar: .show() y .showModal(). Existen diferencias notables entre elegir uno y otro.

Al utilizar el método .show(), el contenido que se encuentre por detrás del modal aún se podrá seleccionar. Mientras que al utilizar el método .showModal() el contenido por detrás estará aislado y no podremos seleccionarlo, por lo que es más recomendable usar este segundo método si deseas que el modal sea lo que más destaque al estar abierto.

Utilizando el método .show():

Utilizando el método .showModal():

Añadiendo animaciones al Elemento Dialog

Como habrás notado, por defecto el Elemento Dialog no tiene animaciones, pero con unas pequeñas modificaciones de CSS y JavaScript podemos hacer que se anime al momento de abrir y de cerrar. Veamos algunos ejemplos.

Hacer que el modal se traslade

El primer ejemplo, haremos que nuestro modal se traslade de arriba hacia abajo cuándo la abrimos y viceversa cuándo lo cerramos.

Empecemos con el HTML y definamos la sintaxis básica de nuestro modal:

<dialog id="modal">
  <p>Este es mi modal</p>
  <button id="btn-close">Ok</button>
</dialog>

<button id="btn">Mostrar modal</button>

Ahora vamos aplicarle estilos a nuestro modal que harán que se traslade:

dialog[open] {
  animation: show 1s ease normal;
}

dialog.hide {
  animation: hide 1s ease normal;
}

@keyframes show {
  from {
    transform: translateY(-110%);
  }
  to {
    transform: translateY(0%);
  }
}

@keyframes hide {
  to {
    transform: translateY(-110%);
  }
}

Creamos dos @keyframes uno lo llamamos show, que será el que traslade nuestro modal desde fuera del viewport de la parte superior hacia abajo. Luego el @keyframes hide, simplemente desliza el modal hacia arriba y fuera del viewport cuándo se cierre.

Ahora añadimos funcionalidad a nuestro modal con JavaScript:

const modal = document.querySelector('#modal')
const btn = document.querySelector('#btn')
const btnClose = document.querySelector('#btn-close')

btn.addEventListener('click', () => {
  modal.showModal()
})

btnClose.addEventListener('click', () => {
  modal.classList.add('hide')

  modal.addEventListener('animationend', function close() {
    modal.classList.remove('hide')
    modal.close()
    modal.removeEventListener('animationend', close)
  })
})

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

  1. Al hacer clic en el botón de cerrar, se agrega la clase .hide.
  2. Establecemos un listener animationend al modal (esto por el @keyframes de la clase .hide), es importante que el callback sea una función nombrada, ya que la ocuparemos más adelante.
  3. Cuando finalice la animación del modal, eliminamos la clase .hide.
  4. Cerramos el modal con el método .close().
  5. Eliminamos el listener animationend al modal y le pasamos la función nombrada, para que la animación no entre en un bucle.

Así se ve en acción nuestro modal:

Hacer un scale

Ahora haremos que nuestro modal se expanda al abrirse y se encoja al cerrarse. Podemos empezar por rehusar el mismo código HTML y JavaScript del ejemplo y sólo modificamos los estilos CSS.

Ahora simplemente usamos la función de CSS scale():

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);
  }
}

Utilizando el pseudo elemento ::backdrop

Una de las ventajas del Elemento Dialog es que se puede utilizar el pseudo elemento ::backdrop para aplicar estilos en el fondo de top-layer mientras se muestra el cuadro de diálogo. Esto ayuda a que el cuadro de diálogo sea más visible y destacado en la página.

Para utilizar el pseudo elemento ::backdrop veremos un ejemplo de cómo podemos hacerlo:

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

En este ejemplo, hemos establecido un efecto de desenfoque en el fondo de la página web mediante la propiedad CSS backdrop-filter. Además, se ha establecido un color de fondo semitransparente mediante la propiedad background-color.

Así se vería:

Ventajas del Elemento Dialog

El Elemento Dialog tiene varias ventajas con respecto a las formas antiguas de crear modales en una página web:

  • Integración con el resto de la página web: El Elemento Dialog se integra perfectamente con el resto de la página web, lo que hace que sea más fácil de utilizar y de personalizar. Aunque en este ejemplo no le hemos dado estilos al Elemento Dialog, puedes utilizar cualquier propiedad CSS para estilizar.
  • Accesibilidad: El Elemento Dialog es accesible para todos los usuarios, independientemente de su dispositivo o navegador. Esto es especialmente importante para los usuarios que utilizan dispositivos especiales como los lectores de pantalla. Gracias a que es un elemento que viene integrado en la plataforma web.
  • Compatibilidad: El Elemento Dialog es compatible con todos los navegadores modernos.

Polyfill para navegadores antiguos

Aunque el Elemento Dialog es compatible con los principales navegadores modernos, en el navegador Safari su soporte es muy reciente por lo que tendremos que recurrir en este caso a utilizar un polyfill para proporcionar la funcionalidad del Elemento Dialog en versiones antiguas del navegador, como por ejemplo en las versiones inferiores a 15.4 tanto para móvil y escritorio.

Para el Elemento Dialog, se puede utilizar el polyfill dialog-polyfill, que proporciona una implementación completa del Elemento Dialog para navegadores antiguos.

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

<head>
  <link rel="stylesheet" type="text/css" href="dist/dialog-polyfill.css" />
  <script src="dialog-polyfill.js" defer></script>
</head>
<body>
  <dialog id="miModal">
    <p>Este es mi modal</p>
    <button id="btn-close">Ok</button>
  </dialog>

  <button id="btn">Mostrar modal</button>

  <script>
    const modal = document.querySelector('#modal')
    const btn = document.querySelector('#btn')
    const btnClose = document.querySelector('#btn-close')

    if (!('showModal' in document.createElement('dialog'))) {
      dialogPolyfill.registerDialog(modal)

      btn.addEventListener('click', () => {
        modal.showModal()
      })

      btnClose.addEventListener('click', () => {
        modal.close()
      })
    }
  </script>
</body>

Y eso sería todo, ahora al hacer pruebas con navegadores dónde no está soportado el Elemento Dialog verás que funciona tal cual lo hace en navegadores modernos.

Si quieres conocer 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 forma sencilla y accesible. Con el Elemento Dialog se pueden crear modales sin necesidad de utilizar la propiedad CSS z-index, lo que facilita la integración con el resto de la página web y mejora la accesibilidad para todos los usuarios.

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

Si bien el Elemento Dialog es compatible con la mayoría de los navegadores modernos, podemos utilizar un polyfill como dialog-polyfill para proporcionar la funcionalidad del Elemento Dialog en navegadores antiguos.

En resumen, el Elemento HTML Dialog es una herramienta útil y accesible para crear modales en una página web. Su integración con el resto de la página web y su compatibilidad con la mayoría de los navegadores modernos hacen que sea una opción interesante para los desarrolladores web que buscan una solución fácil y accesible para crear modales en sus proyectos.

Otras publicaciones

Mira otras publicaciones