dialog
The native HTML modal dialog element with built-in backdrop, focus trapping, and keyboard handling.
Description
The <dialog> element provides a native way to create modal dialogs and pop-up windows. It handles complex accessibility requirements automatically, including focus trapping, ESC to close, and proper ARIA semantics.
There are two ways to open a dialog:
- HTML Invokers API (recommended) -
command="show-modal"/command="close" showModal()/show()- JavaScript methods
Invokers API (Declarative)
The Invokers API lets you open and close dialogs declaratively with HTML attributes - no JavaScript required.
Available Commands
| Command | Description |
|---|---|
show-modal |
Opens dialog as modal (equivalent to showModal()) |
close |
Closes the dialog (equivalent to close()) |
request-close |
Requests closure (can be cancelled with cancel event) |
Browser Support
Invokers API is supported in Chrome 135+, Edge 135+, Safari TP, and Firefox Nightly. Include the polyfill for broader support:
When to Use
- Confirmation dialogs: Confirm destructive actions before proceeding
- Form dialogs: Collect user input in an overlay
- Alert messages: Display important information that requires acknowledgment
- Media lightboxes: Show images or videos in a focused overlay
- Settings panels: Quick access to settings without navigation
When Not to Use
- For inline expandable content - use
<details> - For tooltips or popovers - use
<tool-tip> - For toast notifications - use
<toast-msg> - For non-blocking information - avoid interrupting user flow
showModal() vs show()
The key difference between these two methods affects focus, backdrop, and user interaction:
| Feature | showModal() |
show() |
|---|---|---|
| Backdrop | Yes - via ::backdrop |
No |
| Focus trap | Yes - focus stays inside | No - focus can leave |
| ESC to close | Yes - native behavior | No |
| Inert background | Yes - page is non-interactive | No - page remains interactive |
| Top layer | Yes - above all content | Normal stacking context |
Modal Dialog (Recommended)
Non-Modal Dialog
Backdrop Styling
The ::backdrop pseudo-element styles the overlay behind modal dialogs.
Backdrop Animation
Vanilla Breeze includes smooth fade animation for the backdrop (respects prefers-reduced-motion):
Form method="dialog"
Forms inside dialogs can use method="dialog" to close the dialog when submitted, passing the submit button's value as the return value.
Variants
Basic Dialog
Confirmation Dialog
Dialog with Form
Scrollable Content
Dialog Structure
For consistent styling, use this recommended structure with header, content, and footer:
Structural CSS
JavaScript API
Methods
| Method | Description |
|---|---|
showModal() |
Opens dialog as modal with backdrop and focus trap |
show() |
Opens dialog as non-modal |
close(returnValue?) |
Closes dialog, optionally setting returnValue |
Properties
| Property | Type | Description |
|---|---|---|
open |
boolean | Whether the dialog is currently open |
returnValue |
string | Value set by close() or form submission |
Events
| Event | Description |
|---|---|
close |
Fired when the dialog is closed |
cancel |
Fired when ESC is pressed (can be prevented) |
Accessibility
Native Features
The <dialog> element provides these accessibility features automatically:
- Focus trapping: Tab key cycles through focusable elements inside the dialog
- Focus restoration: Focus returns to the triggering element when closed
- Inert background: Background content is non-interactive when modal is open
- ESC to close: Standard keyboard dismissal (can be prevented)
- ARIA semantics: Automatically has
role="dialog"
Best Practices
- Include a visible close button
- Use a heading in the dialog for screen reader context
- Keep dialogs focused - don't include unrelated content
- Provide keyboard alternatives for all actions
Keyboard Support
| Key | Action |
|---|---|
| Tab | Move focus between focusable elements (trapped inside) |
| Shift + Tab | Move focus backwards (trapped inside) |
| Escape | Close the modal dialog |
Animation
The dialog includes smooth entry animations that respect prefers-reduced-motion:
Size Variants
Use data-size to control dialog width:
| Attribute | Width | Use Case |
|---|---|---|
data-size="s" |
24rem (384px) | Simple confirmations, alerts |
| default | 32rem (512px) | Standard dialogs, forms |
data-size="l" |
48rem (768px) | Complex content, tables |
data-size="full" |
95vw / 95dvh | Full-screen experiences |
Backdrop Click to Close (Optional)
Native dialogs do not close when clicking the backdrop. If you want this behavior, add this small script:
To prevent backdrop close for specific dialogs (e.g., forms with unsaved data), add data-no-backdrop-close:
Drawer Variants
Use data-position to turn any dialog into a slide-in drawer panel. No JavaScript required.
| Attribute | Position | Use Case |
|---|---|---|
data-position="end" |
Right (in LTR) | Navigation, settings panels |
data-position="start" |
Left (in LTR) | Sidebar, filters |
data-position="bottom" |
Bottom | Mobile action sheets, share menus |
data-position="top" |
Top | Banners, announcements |
Drawers inherit all dialog features: Invokers API, ESC to close, focus trapping, backdrop, and data-size variants. Slide animations respect prefers-reduced-motion.
Related Elements
Browser Support
The <dialog> element is supported in all modern browsers.
Invokers API: Chrome 135+, Edge 135+, Safari TP, Firefox Nightly. Use the invokers-polyfill for broader support.