The HTML dialog tag
By Flavio Copes
Learn the native HTML dialog element for accessible modals: showModal, close, form method dialog, backdrop styling, and why it beats div modals.
The HTML dialog tag gives you a native modal without building one from a div.
For years we stacked position: fixed divs and wired up focus trapping by hand. The dialog element handles most of that for you.
Basic markup
<dialog id="settings">
<h2>Settings</h2>
<p>Choose your preferences.</p>
<button id="close-settings">Close</button>
</dialog>
<button id="open-settings">Open settings</button>
The dialog is hidden by default. You open it with JavaScript.
showModal() vs show()
Use showModal() for a true modal. It adds a backdrop, traps focus, and blocks interaction with the page behind it:
const dialog = document.getElementById('settings')
document.getElementById('open-settings').addEventListener('click', () => {
dialog.showModal()
})
Use show() when you want a non-modal panel. No backdrop, no focus trap. The user can still click the rest of the page.
For most cases, showModal() is what you want.
Closing the dialog
Call close() to dismiss it:
document.getElementById('close-settings').addEventListener('click', () => {
dialog.close()
})
You can pass a return value:
dialog.close('saved')
Read it later with dialog.returnValue. Handy when a dialog is part of a workflow.
Pressing Escape closes a modal dialog automatically. You do not need to listen for the key yourself.
Forms inside a dialog
Put a form in the dialog and set method="dialog":
<dialog id="confirm-delete">
<form method="dialog">
<p>Delete this project?</p>
<button value="cancel">Cancel</button>
<button value="delete">Delete</button>
</form>
</dialog>
Clicking a button submits the form and closes the dialog. The button’s value becomes returnValue. This replaces the old JavaScript confirm pattern for simple yes/no prompts.
Styling the backdrop
Use the ::backdrop pseudo-element to style the dimmed area behind the modal:
dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
}
The dialog itself styles like any other element. Border, padding, CSS variables for colors. All the usual rules apply.
Why not a div modal?
A homemade div modal needs extra work:
- Focus trapping so keyboard users stay inside
- Returning focus to the trigger button on close
- Blocking clicks on the page behind
- Managing z-index stacking
The dialog element with showModal() gives you all of that. It also renders in the browser’s top layer, above everything else. No z-index wars.
My advice is to reach for dialog before you build another div-based modal. It is simpler and more accessible out of the box.
Related posts about html: