GitHub

Components / Overlays & Dialogs / Modal

Modal stable

Built on the native dialog element — backdrop blur and Esc-to-close come free.

Preview

Uses: Button — include its CSS alongside this one.

<button class="btn btn-pri btn-md" data-modal-open>Open modal</button>
<dialog class="kmodal" data-modal>
  <div class="modal-in">
    <h3>Send this estimate?</h3>
    <p>Once sent, it can't be undone. Check the recipient and the amount first.</p>
    <div class="row">
      <button class="btn btn-sec btn-md" data-modal-close>Cancel</button>
      <button class="btn btn-pri btn-md" data-modal-close>Send</button>
    </div>
  </div>
</dialog>
.kmodal{border:0;border-radius:16px;padding:0;max-width:420px;width:calc(100% - 40px);box-shadow:0 30px 80px -20px rgba(0,0,0,.4);background:var(--k-bg);color:var(--k-ink);font-family:var(--k-font)}
.kmodal::backdrop{background:rgba(24,24,27,.45);backdrop-filter:blur(3px)}
.modal-in{padding:26px}
.modal-in h3{font-size:16.5px;font-weight:600}
.modal-in p{margin-top:9px;font-size:13.5px;color:var(--k-ink-2);line-height:1.8}
.modal-in .row{display:flex;gap:9px;justify-content:flex-end;margin-top:22px}
const dlg = document.querySelector('[data-modal]');
document.querySelector('[data-modal-open]').addEventListener('click', () => dlg.showModal());
dlg.querySelectorAll('[data-modal-close]').forEach(b => b.addEventListener('click', () => dlg.close()));

Usage

For confirmations that block the flow. Keep the message to one decision.

Accessibility

<dialog> traps focus and closes on Escape natively. Label the primary action with the verb, not "OK".