Dialog

A centered, backdrop-blurred modal built on the native <dialog> element. Open it with showModal().

ClassDoes what
dialogThe dialog itself: fixed, centered, blurred backdrop, hidden unless open
dialog-boxThe panel inside: card surface, scrolls internally, capped width
dialog-headerHeader row inside the panel
dialog-actionsFooter row inside the panel: top border, right-aligned actions

Basic

<button class="btn" data-dialog="demo-dialog">Open dialog</button>

<dialog id="demo-dialog" class="dialog">
  <form method="dialog">
    <article class="dialog-box prose">
      <header class="dialog-header">
        <h3>Dialog heading</h3>
      </header>
      <p>Scrolls internally when the content is taller than the viewport, and locks
        scrolling on the page behind it.</p>
      <footer class="dialog-actions">
        <button value="cancel" class="btn btn-secondary">Cancel</button>
        <button value="ok" class="btn">OK</button>
      </footer>
    </article>
  </form>
</dialog>

The docs script wires [data-dialog] to showModal(). In your own app that is one line: dialog.showModal().

Form nesting

Both nestings work, so the close button needs no JavaScript: dialog > form > .dialog-box and dialog > .dialog-box > form.

<button class="btn" data-dialog="inner-form-dialog">Open</button>

<dialog id="inner-form-dialog" class="dialog">
  <article class="dialog-box prose">
    <form method="dialog">
      <header class="dialog-header"><h3>Rename</h3></header>
      <label class="label">
        Name
        <input type="text" class="input" value="Untitled" />
      </label>
      <footer class="dialog-actions">
        <button value="cancel" class="btn btn-secondary">Cancel</button>
        <button value="save" class="btn">Save</button>
      </footer>
    </form>
  </article>
</dialog>

Classless: the panel is an <code>article</code>, so it picks up the card styling automatically. With classes, <code>.dialog-box</code> includes it.