Dialog

Excerpts from Mary Shelley's Frankenstein (1818). Animation, dragging and reparenting have their own guides: animate-to-from-top-layer, drag, persistent-top-layer-ui.

1. Modal confirmation (declarative)

command="show-modal", aria-labelledby, <form method="dialog">, autofocus on the safe action.

Abandon the work?

“I beheld the wretch—the miserable monster whom I had created.”

2. Modal form with returnValue

A close listener reads dialog.returnValue, then resets it. Pressing Esc sets no value, so it reads "" (dismissed) instead of the previous button. Closing returns focus to the trigger.

Letter to Margaret

No result yet.

3. closedby="any" (light dismiss)

Clicking the backdrop closes it natively. Where closedby is unsupported, a feature-tested pointer fallback does the same.

The sea of ice

“The sea, however, was in a state of ice, and the vast plains stretched before me.”

Click outside, or press Esc, to dismiss.

4. closedby="none" with unsaved changes

Cancel uses request-close, so the cancel handler can ask for confirmation: it shows a message and focuses Discard, which references the message with aria-describedby so a screen reader reads it. Discard appears where no button moves, so a second click on Cancel cannot discard. Only the developer-controlled Discard button force-closes.

Captain's journal

You have unsaved changes. Discard them, or keep editing.

5. Non-modal <dialog popover>

Top layer, page stays interactive, visible close button.

Note

“Beware; for I am fearless, and therefore powerful.”

6. Non-modal dialog.show()

For contrast: not in the top layer, no backdrop, and closedby defaults to none, so this one opts in with closedby="any". Use it only when the panel must not be in the top layer.

Inline

“Nothing is so painful to the human mind as a great and sudden change.”

7. Plain [popover] for a menu

Not everything is a dialog: no modality, no focus trap, just light-dismiss.