Markup
Drop in a <dialog-panel> wrapping a native
<dialog>. The backdrop is auto-created.
Close buttons use data-action-hide-dialog.
<dialog-panel id="my-dialog">
<dialog aria-labelledby="title">
<h2 id="title">Hello</h2>
<p>Your dialog content here.</p>
<button data-action-hide-dialog>Close</button>
</dialog>
</dialog-panel>
<!-- Show it from JavaScript -->
<script>
const panel = document.querySelector('#my-dialog')
panel.show(triggerElement) // opens with animation
panel.hide() // closes with animation
</script>Basic Dialog
Click to open. Close via the button, Escape key, or clicking the backdrop. Focus returns to the trigger element automatically.
State Machine
The component moves through four states, each mapped to a
CSS attribute selector. Animations are pure CSS transitions
driven by [state] changes.
Events & Lifecycle
Four custom events fire at each stage. beforeShow
and beforeHide are cancelable — call
preventDefault() to block the transition.
| Event | Cancelable | When |
|---|---|---|
beforeShow |
yes | Before showModal() is called |
shown |
no | After show transition completes |
beforeHide |
yes | Before hide transition starts |
hidden |
no | After dialog is closed and hidden |
Cancel Prevention
Attach a beforeHide listener and call
preventDefault() to block the dialog from
closing — useful for unsaved-changes confirmations
or required forms.
Nested Dialogs
Place a <dialog-panel> inside another
dialog. Each gets its own backdrop in the top layer.
stopPropagation prevents the inner close from
dismissing the outer.
Positions
Set position="top|bottom|left|right" to slide
the panel in from an edge instead of fading from center.
Useful for cart drawers, mobile menus, action sheets, and
predictive search.
Features
Built on showModal() for free focus trapping, escape handling, and top-layer stacking.
State attribute drives transitions. No JS animation logic — override with your own CSS.
Cross-browser animated backdrop via <dialog-backdrop>, auto-created if missing.
Block show or hide with preventDefault() on beforeShow / beforeHide.
Stack dialogs naturally. Each layer gets its own backdrop with proper z-ordering.
Automatically returns focus to the trigger element when the dialog closes.