HTML dialog: Modal and Non-Modal Examples

HTML dialog showing modal and non-modal behavior

Use the native HTML dialog element to build a modal or non-modal interface without recreating its focus and keyboard behavior with a generic div. The example below is a complete HTML dialog with two triggers, a method=dialog form, and JavaScript for opening and closing it.

When a dialog is shown, the element receives the open state. The opening method determines whether the rest of the page remains interactive.

Create an HTML dialog box with a form close action

Place the trigger buttons and dialog in the document. A form with method=”dialog” closes its nearest dialog when a submit button is activated. The clicked button’s value becomes the dialog’s return value.

Markup: <button type=”button” id=”open-modal”>Open modal</button> <button type=”button” id=”open-nonmodal”>Open non-modal</button> <dialog id=”account-dialog”> <form method=”dialog”> <h2>Account settings</h2> <p>Choose an action for this account.</p> <button value=”cancel”>Cancel</button> <button value=”save”>Save</button> </form> </dialog>

The two buttons use type=”button” so they do not submit a surrounding form. The dialog’s Cancel and Save buttons are submit controls for the dialog form, so either one closes the dialog without requiring a custom click handler.

Open an HTML5 dialog with show() or showModal()

Call show() for non-modal behavior. The dialog opens, but users can still interact with the rest of the page. Call showModal() for modal behavior. The browser renders a backdrop, keeps interaction inside the dialog, and manages modal focus.

JavaScript: const dialog = document.querySelector(“#account-dialog”); const modalButton = document.querySelector(“#open-modal”); const nonModalButton = document.querySelector(“#open-nonmodal”); modalButton.addEventListener(“click”, () => { dialog.showModal(); }); nonModalButton.addEventListener(“click”, () => { dialog.show(); });

  • show() opens the dialog without making the document modal.
  • showModal() opens it as a modal dialog and enables ::backdrop styling.
  • Both methods set dialog.open to true. Do not call either method again while the same dialog is already open.

Close the dialog, handle events, and read a return value

Pressing Escape on a modal dialog normally fires the cancel event and then closes the dialog. Listen for cancel when you need to prevent that default behavior, such as when unsaved changes require confirmation. The close event fires after any closing method, including a dialog-form submission.

Use close(value) to close the element from JavaScript. Its optional value is exposed through dialog.returnValue. The form buttons above return cancel or save.

Closing and events: dialog.addEventListener(“cancel”, (event) => { /* event.preventDefault() keeps it open */ }); dialog.addEventListener(“close”, () => { console.log(dialog.returnValue); }); dialog.close(“programmatic”);

After close(), the open property becomes false. The close event is the suitable place to update the page based on the selected value, while the cancel event is the suitable place to intercept Escape before the default close occurs.

Style the HTML dialog and its ::backdrop

Target the dialog directly for its panel appearance. The ::backdrop pseudo-element applies to the viewport layer created by showModal(); a non-modal dialog does not receive that modal backdrop.

CSS: dialog { border: 0; border-radius: 0.5rem; padding: 1.5rem; max-width: 32rem; } dialog::backdrop { background: rgb(0 0 0 / 55%); }

Keep the close controls inside the dialog form when their purpose is to return a user-selected result. Use close(value) for programmatic outcomes that are not represented by a form button.