Skip to content

ExpressiveCSS

Browse documentation

Dialogs

Important prompts in a user flow, each for a single task.

View as Markdown

Use a dialog when people need to act on information: to confirm a high-risk action, finish one task, or read the copy that belongs to that task. The basic and full-screen variants use the same element. There is no modal-header, modal-content, or modal-footer class.

Tokens follow the M3 dialog spec. The basic container is surface-container-high, 28dp corners, 280 to 560dp wide, and elevation 3. The headline is headline-small / on-surface. Supporting text is body-medium / on-surface-variant. Actions are text buttons, end aligned, with an 8dp gap. Padding is 24dp (16dp between the headline and the body). The scrim is --md-comp-scrim-color with a 12px blur. Opening with showModal() also stops the page behind it from scrolling.

Open it with showModal() and close it with close(). These are Dialog API methods, not a plugin.

Basic

The <dialog> is the surface and a heading is the headline. A <p>, or a wrapping <div>, is supporting text. The last child <form method="dialog"> or <nav> is the action row. An optional leading icon centers the headline. Add an <hr> as the divider when extra content follows the copy.

Basic dialog title

A dialog is a modal window that appears in front of app content to provide critical information or ask for a decision.

Use location services?

Let the app use your location to suggest nearby stops and live arrival times.

Reset settings?

This will reset your app preferences back to their default settings. The following accounts will also be signed out:


  • leevillanuevanotes@google.com
  • alloalejandro@google.com
  • oliortega@google.com

<button type="button" onclick="document.getElementById('dialog1').showModal()">
  Show
</button>

<dialog id="dialog1" aria-labelledby="basic-dialog-title-title">
  <h2 id="basic-dialog-title-title">Basic dialog title</h2>
  <p>A dialog is a modal window that appears in front of app content.</p>
  <form method="dialog">
    <button type="submit" value="cancel">Cancel</button>
    <button type="submit" value="accept">Accept</button>
  </form>
</dialog>

When someone presses a submit button in a <form method="dialog">, the browser closes the dialog and sets dialog.returnValue from the button's value. Action buttons are text buttons by default. Add filled, tonal, or outlined if you need more emphasis. Tapping the scrim closes it too, but only if the press and the release both miss the dialog. For docked panes, see Side sheet and Bottom sheet.

Full-screen

Add max when the task needs the whole viewport, typically on compact windows or whenever the dialog holds a form. A full-screen dialog has no scrim and no corner radius. A <header> is the 64dp top bar: a close icon, a title-large headline, and the confirming text button. Body content is inset 24dp.

Full-screen dialog title

<dialog class="max" aria-labelledby="full-screen-dialog-title-title">
  <header>
    <button type="button" aria-label="Close" onclick="this.closest('dialog').close()">
      <span class="material-symbols" aria-hidden="true">close</span>
    </button>
    <h2 id="full-screen-dialog-title-title">Full-screen dialog title</h2>
    <form method="dialog">
      <button type="submit" value="save">Save</button>
    </form>
  </header>
  <div>…</div>
</dialog>

Confirm from script

Expressive.Dialogs.confirm() asks a yes-or-no question and returns a promise. It builds a basic dialog with role="alertdialog", opens it with showModal(), and removes it once it closes. The promise resolves true when the person picks the confirm button and false on Cancel, Escape or a scrim tap.

const ok = await Expressive.Dialogs.confirm({
  headline: 'Delete draft?',
  text: 'The draft and its attachments are removed.',
  confirm: 'Delete'
});
if (ok) deleteDraft();

text is the question and is required. headline is optional. With a headline, the dialog is named by it and described by the text; without one, the text names it. All four strings are set as text, so markup in them is shown, not parsed. If page code removes the open dialog, for example on a route change, the promise resolves false.

Focus starts on Cancel, the less destructive action, and the browser returns it to the element that had focus before the call. Label the confirm button with the action it takes, such as "Delete" or "Discard", rather than the "OK" default.

confirm and cancel set the button labels for one call. Expressive.Dialogs.i18n holds the defaults, { confirm: 'OK', cancel: 'Cancel' }; assign to it to change them for every later call. With the modular entry, confirm() works without Dialogs.Init(), but a scrim tap closes the dialog only after Init() runs.

Expressive.Dialogs.i18n.confirm = 'Aceptar';
Expressive.Dialogs.i18n.cancel = 'Cancelar';

Methods

Call these on the <dialog> element. See HTMLDialogElement for the full API.

.showModal()

Opens the dialog as a modal. A basic dialog gets the scrim, and a full-screen dialog fills the page.

dialog.showModal();
.close()

Closes the dialog.

dialog.close();

A tap or click on the scrim also closes a basic dialog. Both ends of the gesture have to land outside the dialog's box, so a drag that starts on the dialog, such as selecting text or missing a button, cannot dismiss it. Set closedby="none" or closedby="closerequest" to opt out.

Tokens

Override these on the <dialog> to change the surface or width. A basic dialog fades in and grows from 96% on springs, so motion="expressive" applies to it. It closes at once. When the user requests reduced motion, it opens without moving. Full-screen dialogs and sheets keep their own motion.

Token Default
--md-comp-basic-dialog-container-color --md-sys-color-surface-container-high
--md-comp-basic-dialog-container-shape 28px
--md-comp-basic-dialog-container-min-width 280px
--md-comp-basic-dialog-container-max-width 560px
--md-comp-basic-dialog-scrim-blur 12px
--md-comp-basic-dialog-easing, --md-comp-basic-dialog-duration The default spatial spring, which grows the dialog from 96% as it opens
--md-comp-basic-dialog-effects-easing, --md-comp-basic-dialog-effects-duration The fast effects spring, used for the fade-in
--md-comp-scrim-color --md-sys-color-scrim at 32%

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow