Kodokon kodokon.com

HTML interactivo moderno: dialog, details, popover, contenteditable

Reemplaza tus bibliotecas de UI con las primitivas nativas del HTML moderno: diálogos modales, acordeones exclusivos, popovers y regiones editables.

10 min · 3 preguntas

Abrir esta lección en Kodokon

<dialog> resuelve de forma nativa lo que años de bibliotecas modales han improvisado a golpe de parches. showModal() proyecta el elemento en la capa superior (top layer) - por encima de cualquier z-index -, hace que el resto del documento sea inerte (sin foco, sin clics) y expone el pseudoelemento ::backdrop. show(), en cambio, muestra un diálogo no modal, sin inercia y sin backdrop. El reciente atributo closedby=any añade el cierre al hacer clic fuera.

HTML
<dialog id="confirm-dlg">
  <form method="dialog">
    <p>Delete this item?</p>
    <button value="cancel">Cancel</button>
    <button value="ok">Confirm</button>
  </form>
</dialog>
Un formulario method=dialog cierra el diálogo sin una petición de red.

Un <form method=dialog> cierra el diálogo sin un envío de red: el value del botón que lo activa se convierte en dialog.returnValue, que el evento close te permite leer. La tecla Escape cierra un diálogo modal emitiendo primero cancel, que puedes cancelar con preventDefault() si hay una entrada en curso.

JAVASCRIPT
const dlg = document.getElementById("confirm-dlg");
dlg.showModal();
dlg.addEventListener("close", () => {
  console.log(dlg.returnValue); // "ok" or "cancel"
});
Recuperando la elección del usuario al cerrar.

La API Popover cubre menús, tooltips enriquecidos y toasts sin JavaScript: pon popover en el elemento y popovertarget en un botón, y el navegador se encarga de la capa superior, del cierre ligero (light dismiss) (clic fuera, Escape) y del cierre mutuo de los popovers auto. A diferencia de showModal(), un popover no hace que la página sea inerte. Los eventos beforetoggle y toggle te permiten cancelar u observar cada transición.

HTML
<button popovertarget="user-menu">Menu</button>
<div id="user-menu" popover>
  <button>Profile</button>
  <button>Log out</button>
</div>
Un menú completo, sin una sola línea de JavaScript.

<details> proporciona contenido colapsable accesible sin ningún script, y un atributo name compartido crea un grupo exclusivo: abrir uno cierra los demás. El evento toggle se dispara ahí en cada cambio de estado. Del lado de la edición, contenteditable convierte cualquier elemento en un área de entrada enriquecida; su variante plaintext-only prohíbe cualquier marcado, y el evento beforeinput reemplaza con ventaja la API obsoleta document.execCommand.

HTML
<details name="faq" open>
  <summary>Delivery time?</summary>
  <p>Within 48 hours.</p>
</details>
<details name="faq">
  <summary>Return policy?</summary>
  <p>Within 30 days.</p>
</details>
El name compartido produce un acordeón exclusivo nativo.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué aporta showModal() frente a show()?
    • Bloquea la ejecución de JavaScript hasta que se cierra el diálogo
    • Coloca el diálogo en la capa superior, hace que el resto del documento sea inerte y habilita ::backdrop
    • Solo impide que la página se desplace
  2. ¿Qué produce un atributo name idéntico en varios <details>?
    • Se envían juntos en el formulario padre
    • Nada: name no es un atributo válido en details
    • Un acordeón exclusivo: abrir uno cierra automáticamente los demás
  3. ¿Cuál es la diferencia de comportamiento entre un popover auto y un popover manual?
    • auto obtiene el cierre ligero (clic fuera, Escape) y cierra los demás popovers auto; manual permanece abierto hasta que se cierra explícitamente
    • manual no puede colocarse en la capa superior
    • auto se abre por sí solo cuando se carga la página