Presentamos la API de popover

Los pop-ups están en todas partes de la Web. Puedes verlos en menús, sugerencias de activación y diálogos, que pueden manifestarse como parámetros de configuración de la cuenta, widgets de divulgación y vistas previas de tarjetas de productos. A pesar de la prevalencia de estos componentes, compilarlos en navegadores sigue siendo sorprendentemente engorroso. Debes agregar secuencias de comandos para administrar el enfoque, los estados de apertura y cierre, los hooks accesibles en los componentes, las vinculaciones de teclado para ingresar y salir de la experiencia, y todo esto incluso antes de comenzar a compilar la funcionalidad principal, útil y única de tu popover.

Para resolver este problema, los navegadores incorporarán un nuevo conjunto de APIs de HTML declarativas para compilar ventanas emergentes, comenzando con la API de popover en Chromium 114.

El atributo popover

Navegadores compatibles

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 125.
  • Safari: 17.

Origen

En lugar de administrar toda la complejidad por tu cuenta, puedes permitir que el navegador la controle con el atributo popover y el conjunto de funciones subsiguientes. Los pop-overs HTML admiten lo siguiente:

  • Asciende a la capa superior. Las ventanas emergentes aparecerán en una capa independiente sobre el resto de la página, de modo que no tengas que preocuparte por el índice z.
  • Función de descarte de luz Si haces clic fuera del área del cuadro emergente, este se cerrará y se restablecerá el enfoque.
  • Administración predeterminada del enfoque. Si abres el cuadro emergente, el siguiente punto de parada de pestaña se ubicará dentro de él.
  • Vinculaciones de teclas accesibles. Si presionas la tecla esc, se cerrará la ventana emergente y se devolverá el enfoque.
  • Vinculaciones de componentes accesibles. Conectar un elemento de popover a un activador de popover semánticamente

Ahora puedes crear ventanas emergentes con todas estas funciones sin usar JavaScript. Un popover básico requiere tres elementos:

  • Un atributo popover en el elemento que contiene el popover
  • Un id en el elemento que contiene el popover.
  • Un popovertarget con el valor del id del popover en el elemento que lo abre.
<button popovertarget="my-popover"> Open Popover </button>

<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>

Ahora tienes un popover básico completamente funcional.

Esta ventana emergente se puede usar para transmitir información adicional o como un widget de divulgación.

Valores predeterminados y anulaciones

De forma predeterminada, como en el fragmento de código anterior, configurar un cuadro emergente con un popovertarget significa que el botón o elemento que lo abre lo abrirá y cerrará. Sin embargo, también puedes crear ventanas emergentes explícitas con popovertargetaction. Esto anula la acción de activación predeterminada. Estas son algunas opciones de popovertargetaction:

popovertargetaction="show": Muestra el popover. popovertargetaction="hide": Oculta el popover.

Con popovertargetaction="hide", puedes crear un botón "Cerrar" dentro de una ventana emergente, como en el siguiente fragmento:

<button popovertarget="my-popover" popovertargetaction="hide">
    <span aria-hidden="true">❌</span>
    <span class="sr-only">Close</span>
</button>

Ventanas emergentes automáticas y manuales

El uso del atributo popover por sí solo es un atajo para popover="auto". Cuando se abra, el popover predeterminado forzará el cierre de otros pop-ups automáticos, excepto los pop-ups de ancestros. Se puede descartar con la función de descarte ligero o con un botón de cierre.

Por otro lado, configurar popover=manual crea otro tipo de popover: uno manual. No fuerzan el cierre de ningún otro tipo de elemento ni se cierran con la acción de descartar con la luz. Debes cerrarlos con un temporizador o una acción de cierre explícita. Los tipos de ventanas emergentes adecuados para popover=manual son elementos que aparecen y desaparecen, pero que no deben afectar al resto de la página, como una notificación de tostada.

Si exploras la demostración anterior, verás que hacer clic fuera del área del cuadro emergente no lo oculta. Además, si hubiera otros popovers abiertos, no se cerrarían.

Para revisar las diferencias, haz lo siguiente:

Ventanas emergentes con popover=auto:

  • Cuando se abra, cierra de manera forzosa otros pop-ups.
  • Se puede descartar con la luz.

Notificaciones emergentes con popover=manual:

  • No cierres de forma forzosa ningún otro tipo de elemento.
  • No descartar con la luz. Ciérralos con un botón de activación o una acción de cierre.

Aplica diseño a los menús flotantes

Hasta ahora, aprendiste sobre ventanas emergentes básicas en HTML. Sin embargo, también hay algunas funciones de diseño interesantes que se incluyen con popover. Una de ellas es la capacidad de aplicar diseño a ::backdrop.

En los popovers de auto, esta es una capa directamente debajo de la capa superior (donde se encuentra el popover), que se encuentra sobre el resto de la página. En el siguiente ejemplo, se le asigna un color semitransparente a ::backdrop:

#size-guide::backdrop {
  background: rgb(190 190 190 / 50%);
}

La diferencia entre un popover y un dialog

Es importante tener en cuenta que el atributo popover no proporciona semántica por sí solo. Si bien ahora puedes compilar experiencias similares a diálogos modales con popover="auto", existen algunas diferencias clave entre ambos:

Un elemento dialog abierto con dialog.showModal (un diálogo modal) es una experiencia que requiere una interacción explícita del usuario para cerrar el diálogo modal. Un popover admite la eliminación de la luz. Un dialog modal no lo hace. Un diálogo modal hace que el resto de la página se vuelva inerte. Un popover no lo hace.

.

La demostración anterior es un diálogo semántico con comportamiento emergente. Esto significa que el resto de la página no es inerte y que el cuadro emergente de diálogo tiene un comportamiento de descarte ligero. Puedes compilar este diálogo con el comportamiento de popover con el siguiente código:

<button popovertarget="candle-01">
  Quick Shop
</button>
<dialog popover id="candle-01">
  <button class="close-btn" popovertarget="candle-01" popovertargetaction="hide">...</button>
  <div class="product-preview-container">
    ...
  </div>
</dialog>

Próximamente

Entrada y salida interactivas

La capacidad de animar propiedades discretas, incluidas las animaciones hacia y desde display: none, y desde y hacia la capa superior, aún no están disponibles en los navegadores. Sin embargo, está planificado para una próxima versión de Chromium, muy después de esta.

Con la capacidad de animar propiedades discretas y usar :popover-open y @starting-style, podrás configurar estilos antes y después del cambio para habilitar transiciones fluidas cuando abras y cierres los pop-overs. Tomemos el ejemplo anterior. Animarlo dentro y fuera se ve mucho más fluido y admite una experiencia del usuario más fluida:

Posicionamiento del ancla

Las ventanas emergentes son excelentes cuando quieres posicionar una alerta, una ventana modal o una notificación en función del viewport. Sin embargo, las ventanas emergentes también son útiles para menús, información sobre herramientas y otros elementos que deben posicionarse en relación con otros elementos. Aquí es donde entra en juego el anclaje de CSS.

En la siguiente demostración de menú radial, se usa la API de popover junto con el posicionamiento de ancla de CSS para garantizar que el popover #menu-items siempre esté anclado a su activador de activación, el botón #menu-toggle.

La configuración de los anclajes es similar a la de los pop-overs:

<button id="menu-toggle" popovertarget="menu-items">
  Open Menu
</button>
<ul id="menu-items" popover anchor="menu-toggle">
  <li class="item">...</li>
  <li class="item">...</li>
</ul>

Para configurar un ancla, debes asignarle un id (en este ejemplo, #menu-toggle) y, luego, usar anchor="menu-toggle" para conectar los dos elementos. Ahora, puedes usar anchor() para aplicar diseño al popover. Un menú emergente centrado que está anclado al modelo de referencia del botón de activación de la fijación podría tener el siguiente diseño:

#menu-items {
  bottom: anchor(bottom);
  left: anchor(center);
  translate: -50% 0;
}
.

Ahora tienes un menú emergente completamente funcional que está anclado al botón de activación y tiene todas las funciones integradas de la ventana emergente, sin necesidad de usar JavaScript.

Conclusión

La API emergente es el primer paso de una serie de nuevas capacidades para facilitar la creación de aplicaciones web y más accesible de forma predeterminada. Me entusiasma ver cómo usas los popovers.

Lecturas adicionales