Skip to content

TicFrame v5.7.0-alpha.1 is available - read the changelog.

TicFrame

Components

Dialog

Dialog and Modal are the same underlying <dialog class="tf-modal"> element. Modal documents the composed application patterns (headers, footers, sizes, scrollable bodies). This page documents the native element contract itself — including the one thing Modal's own patterns don't cover: a non-modal dialog that doesn't block the rest of the page.

How It Works

Every dialog is opened through TicFrame.Modal.show() (or a data-tf-toggle="modal" trigger), which picks between the browser's two native open methods based on one attribute.

By default a dialog opens with the native showModal(): it gets a ::backdrop, blocks interaction with the rest of the page, and traps focus. Add data-tf-dialog-modal="false" and TicFrame uses show() instead — no backdrop, no focus trap, the page behind stays fully usable.

Alert dialogs

Add role="alertdialog" for a dialog that interrupts to demand a decision (typically a destructive confirmation) — screen readers announce it more assertively than a plain dialog.

Scroll lock scope

Background scroll only locks while a modal dialog is open. A non-modal dialog never locks scroll, even if a modal one is opened afterward and then closed while the non-modal one is still up.

Escape behavior

The browser only wires Escape-to-close for dialogs opened with showModal(). A non-modal dialog needs an explicit data-tf-dismiss="modal" control — Escape does nothing to it, which is native, not a TicFrame gap.

Live Examples

Modal dialog (default)

Blocks the rest of the page. This is the same behavior Modal's patterns all build on.

Modal dialog

Background scroll is locked and the rest of the page can't be interacted with until this closes.

HTML
<button type="button" class="tf-btn tf-btn-primary" data-tf-toggle="modal" data-tf-target="#dialog-modal-demo">Open modal dialog</button>
<dialog id="dialog-modal-demo" class="tf-modal tf-modal-sm tf-modal-center" aria-labelledby="dialog-modal-demo-title">
  <div class="tf-modal-body">
    <h3 id="dialog-modal-demo-title">Modal dialog</h3>
    <p>Background scroll is locked...</p>
    <button type="button" data-tf-dismiss="modal">Close</button>
  </div>
</dialog>

Non-modal dialog

data-tf-dialog-modal="false" on the dialog itself. No backdrop, no scroll lock — try scrolling or clicking elsewhere on the page while this is open.

Non-modal dialog

The page behind this stays interactive — there's no backdrop and no focus trap.

HTML
<button type="button" class="tf-btn" data-tf-toggle="modal" data-tf-target="#dialog-nonmodal-demo">Open non-modal dialog</button>
<dialog id="dialog-nonmodal-demo" class="tf-modal tf-modal-sm" data-tf-dialog-modal="false" aria-labelledby="dialog-nonmodal-demo-title">
  <div class="tf-modal-body">
    <h3 id="dialog-nonmodal-demo-title">Non-modal dialog</h3>
    <p>The page behind this stays interactive...</p>
    <button type="button" data-tf-dismiss="modal">Dismiss</button>
  </div>
</dialog>

Alert dialog

role="alertdialog" for a destructive confirmation — the safe action is first and focused by default.

Delete this project?

This can't be undone.

HTML
<dialog class="tf-modal tf-modal-sm tf-modal-center" role="alertdialog"
        aria-labelledby="dialog-alert-demo-title" aria-describedby="dialog-alert-demo-desc">
  <div class="tf-modal-body">
    <h3 id="dialog-alert-demo-title">Delete this project?</h3>
    <p id="dialog-alert-demo-desc">This can't be undone.</p>
    <button type="button" autofocus data-tf-dismiss="modal">Cancel</button>
    <button type="button" class="tf-btn-danger" data-tf-dismiss="modal">Delete</button>
  </div>
</dialog>

Accessibility

RequirementTicFrame guidance
Namearia-labelledby pointing at the visible title, for both modal and non-modal dialogs.
Alert dialogsUse role="alertdialog" plus aria-describedby for destructive confirmations; keep it modal so the decision can't be skipped.
Non-modal focusTicFrame still moves focus into a non-modal dialog on open and restores it on close — only the trap and backdrop are skipped, not focus management.
EscapeOnly closes modal dialogs (native browser behavior). Give a non-modal dialog a visible dismiss control since users can't rely on Escape.

API Reference

Attributes

AttributeTypeDefaultDescription
data-tf-dialog-modal"false" (only meaningful value)unset (modal)Opens with native show() instead of showModal(): no backdrop, no focus trap, no scroll lock.

Triggers, dismiss buttons, methods, and events are shared with Modal — see the Modal API reference. TicFrame.Modal.show() reads data-tf-dialog-modal off the dialog element itself, so the same method opens both kinds.

Troubleshooting

SymptomFix
Escape doesn't close my non-modal dialogExpected — only showModal()-opened dialogs get native Escape handling. Add a visible dismiss button.
Non-modal dialog still blocks the pageConfirm data-tf-dialog-modal="false" is on the <dialog> element itself, not the trigger button.
Background scroll stays locked after closing a non-modal dialogThis shouldn't happen — non-modal dialogs never lock scroll in the first place. Check whether a separate modal dialog is also open.
Alert dialog closes on backdrop click when it shouldn'tAdd data-tf-modal-backdrop="static" to require an explicit button choice.