Skip to content

Modal

CSS

A modal is a focused task on top of the page: confirm a delete, a short form, a warning. Use <dialog class="k-modal" popover>. The Popover API opens and closes it.

A button with popovertarget matching the dialog id opens it. The same attribute with popovertargetaction="hide" closes it. Escape still dismisses. A click on the dimmed backdrop doesn’t, unless you put a .k-modal__scrim hide button in the dialog.

Put title, body, and actions inside .k-modal__box. That box is the raised surface. The dimmed page is ::backdrop. The scrim sits on that dimmed area so a click closes the dialog without hitting the page underneath.

ClassTypeDescription
k-modalcomponentThe dialog. Pair it with the popover attribute so the browser opens it.
k-modal__scrimpartHide button covering the dimmed page, so a backdrop click closes.
k-modal__boxpartThe raised surface holding everything visible.
k-modal__titlepartName of the task. Any element; a heading is fine when the outline needs one.
k-modal__bodypartThe copy or the form.
k-modal__actionspartRow of buttons, aligned to the end.

A destructive confirm. Open it from the button. Cancel, Delete, and a click on the dimmed backdrop all hide it.

Delete file

This will remove report.pdf. You can’t undo this.

<button type="button" class="k-btn k-btn--primary" popovertarget="confirm">
Open modal
</button>
<dialog id="confirm" class="k-modal" popover>
<button
type="button"
class="k-modal__scrim"
popovertarget="confirm"
popovertargetaction="hide"
aria-label="Close"
></button>
<div class="k-modal__box">
<h3 class="k-modal__title">Delete file</h3>
<p class="k-modal__body">This will remove report.pdf. You can't undo this.</p>
<div class="k-modal__actions">
<button type="button" class="k-btn k-btn--ghost" popovertarget="confirm" popovertargetaction="hide">
Cancel
</button>
<button type="button" class="k-btn k-btn--primary" popovertarget="confirm" popovertargetaction="hide">
Delete
</button>
</div>
</div>
</dialog>

The element is a <dialog popover>. The Popover API handles Escape and focus. Backdrop close is a .k-modal__scrim button with popovertargetaction="hide" and aria-label="Close". Title the dialog with .k-modal__title. Don’t trap focus yourself. The browser already does.

Do

  • Use <dialog class="k-modal" popover>.
  • Match popovertarget to the dialog id.
  • Put a .k-modal__scrim hide button in the dialog, with aria-label="Close".
  • Put title, body, and actions in .k-modal__box.

Don’t

  • Call mount. The Popover API already opens it.
  • Trap focus yourself.
  • Skip the scrim and expect a click on ::backdrop to close it.
  • Open a modal for a tooltip or a toast.