Dialog
A dialog asks a question the reader must answer before going on, and keeps the rest of the page inert until it closes. Its variant sets how much screen the question takes: basic for one decision, full screen for a series of tasks. A form inside it closes the dialog and names the button that did, with no handler to write. Each button below opens a different dialog.
Reference docs
Choosing a pop-up surface
Five kinds of surface open over the page for a moment. Each suits a different job:
- Dialog: a question the reader must answer before going on, such as Discard unsaved changes?
- Popover: extra content opened from a control and dismissed by clicking away, such as a small settings panel.
- Menu: a short list of commands opened from a button, such as Rename, Duplicate, Delete.
- Plain tooltip: a short label shown on hover or focus, such as what an icon button does.
- Rich tooltip: a heading, a few lines of text and an optional action shown next to the element it describes, such as what a new feature does.
Three jobs belong elsewhere. A message about something that just happened is a toast, content that stays on the page is a card, and a short set of creation actions opened from a floating button is a FAB menu.
Choosing a variant
Two variants set how much of the screen a dialog takes, from least to most:
- Basic: one decision or a short task, such as confirming a deletion or renaming a file.
- Full screen: a series of tasks, such as filling in a new event's title, time, and guests on a phone.
Built in
- The page behind an open dialog is inert, and its scrolling is locked until the dialog closes.
- Tab and Shift+Tab stay inside the dialog, wrapping from its last control to its first.
- Escape and a click on the scrim close it, each firing a cancelable
cancelevent first; andignore-escape-key turn either off.ignore-scrim-click - A
<form method="dialog">in its content closes it and sets to thereturn-valuevalueof the button that submitted it. - Content taller than the dialog scrolls inside it, with a shadow or a divider at the edge that has more (
).scroll-indicator - The full-screen variant draws its own close button and moves the actions into its headline bar (
).actions-placement
Hidden content renders when first shown
A dialog's panel, headline, content, and actions do not exist until it first opens. Each opening starts like the first, scrolled to the top. Your content stays as it was, so a half-filled form is still half filled, and returnValue stays readable after the dialog closes. After you open the dialog, wait for updateComplete and everything is there for your code to reach at once. See Hidden content renders when first shown.
Starting fresh each time
A dialog never clears what your app put in it, so a form the user abandoned is still filled when the dialog opens again. If each opening should start empty, reset the content when the dialog reports it has closed.
dialog.addEventListener("toggle", (event) => {
if (event.newState === "closed") dialog.querySelector("form")?.reset();
});
React and Blazor use onToggle and OnToggle; see Starting each opening empty.
Using dialogs well
- Open a dialog only for a question the reader must answer now; show anything they can ignore in a Popover or a Menu.
- Give every dialog a headline that states its question, or an
aria-labelwhen it has no headline. - Set
totypealertonly for an important message that needs a response, such as confirming a destructive action. - Put the confirming action last, after the one that dismisses: Cancel, then Delete.
- Put
autofocuson the control that should take focus when the dialog opens, usually the safest action. - Open a dialog over another dialog only from a full-screen one.
These rules follow Material 3 Expressive's guidance for dialogs, on material.io.
Variants
variantbasicicon slot above its headline. full-screenno-close-button
Opening and closing
Set openshow(), to open a dialog; clear openclose(), to close it. close() takes an optional value, which becomes return-valuebeforetoggle event before its animation, and a toggle event after it; both carry oldState and newState. Cancel beforetoggle to keep the dialog shut when newState is "open", or to keep it open when newState is "closed". A listener on the dialog hears only its own beforetoggle and toggle, never those of an element inside it.
Dismissing
Escape and a click on the scrim both fire cancel on the dialog, then close it with the usual beforetoggle and toggle; cancel that cancel event to keep it open. cancel does not bubble, so listen on the dialog itself. Set ignore-escape-keyignore-scrim-clickcancel fires for it. Keep at least one way out: with both set, and no-close-button
Forms
Put a <form method="dialog"> in the content slot, and give each button in the actions slot the form's id in its form attribute, a type of submit, and a value. Submitting the form closes the dialog, and return-valuevalue of the button that submitted it; read it in a toggle listener once newState is "closed". A form that fails validation does not submit, so the dialog stays open. The preview blocks form submission in some browsers, so each button here also calls close() with its value; on your own page, the form alone closes the dialog.
Alert dialogs
With typealert, screen readers announce the dialog as an alert dialog rather than a plain one. Leave type
Actions placement
actions-placementactions slot independently of the variant. autobottomheadline
Animation
animationfadeslidenonefade
Scroll indicator
Content taller than the dialog scrolls inside it, vertically only. scroll-indicatorshadowdividernoneshadow
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
actionsPlacement | actions-placementauto, bottom, headline | DialogActionsPlacementDialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the actions slot appears, independently of variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
animation | animationfade, none, slide | DialogAnimationDialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
ignoreEscapeKey | ignore-escape-key | booleandefault false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
ignoreScrimClick | ignore-scrim-click | booleandefault false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
maskContent | mask-content | boolean | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
noCloseButton | no-close-button | booleandefault false | Hides the built-in close button in the full-screen variant's headline. Set it alongside ignore-scrim-click and ignore-escape-key when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
noFocusTrap | no-focus-trap | booleandefault false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
open | open | booleandefault false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
returnValue | return-value | string | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The return-value attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
scrollIndicator | scroll-indicatordivider, none, shadow | ScrollIndicatorScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
type | type | string | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
variant | variantbasic, full-screen | DialogVariantDialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Slots
| Slot | Description |
|---|---|
icon | An icon above the headline, in the basic variant only. Hidden from screen readers. |
headline | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
content | Main scrollable content area |
actions | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
Events
| Event | Type | Detail | Description |
|---|---|---|---|
beforetoggle | ToggleEvent | — | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
toggle | ToggleEvent | — | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
cancel | Event | — | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that ignore-scrim-click or ignore-escape-key turns off. It is cancelable. |
Methods
| Method | Returns | Description |
|---|---|---|
close(returnValue?: string) | Promise<void> | Closes the dialog and fires a cancelable beforetoggle event. After a dialog's animation, a toggle event is fired. |
show() | Promise<void> | Opens the dialog and fires a cancelable beforetoggle event. After a dialog's animation, a toggle event is fired.Add an autofocus attribute to a child of the dialog that should receive focus after opening. |
show() resolves after the toggle that reports "open", and close() after the one that reports "closed". A second close() while one is in flight waits for the first.
Props
| Prop | Type | Description |
|---|---|---|
actionsPlacement | DialogActionsPlacementTypeDialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the slot="actions" child appears, independently of variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
animation | DialogAnimationTypeDialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
ignoreEscapeKey | booleandefault false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
ignoreScrimClick | booleandefault false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
maskContent | boolean | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
noCloseButton | booleandefault false | Hides the built-in close button in the full-screen variant's headline. Set it alongside ignoreScrimClick and ignoreEscapeKey when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
noFocusTrap | booleandefault false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
open | booleandefault false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
returnValue | string | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The returnValue attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
scrollIndicator | ScrollIndicatorTypeScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
type | string | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
variant | DialogVariantTypeDialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Children
| Child | Description |
|---|---|
a child with slot="icon" | An icon above the headline, in the basic variant only. Hidden from screen readers. |
a child with slot="headline" | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
a child with slot="content" | Main scrollable content area |
a child with slot="actions" | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
Events
| Prop | Argument | Description |
|---|---|---|
onBeforeToggle | ToggleEvent | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
onToggle | ToggleEvent | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
onCancel | Event | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that ignoreScrimClick or ignoreEscapeKey turns off. It is cancelable. |
Methods
Call these on the element the ref holds.
| Method | Returns | Description |
|---|---|---|
close(returnValue?: string) | Promise<void> | Closes the dialog and fires a cancelable beforetoggle event. After a dialog's animation, a toggle event is fired. |
show() | Promise<void> | Opens the dialog and fires a cancelable beforetoggle event. After a dialog's animation, a toggle event is fired.Add an autofocus attribute to a child of the dialog that should receive focus after opening. |
show() resolves after the toggle that reports "open", and close() after the one that reports "closed". A second close() while one is in flight waits for the first.
Parameters
| Parameter | Type | Description |
|---|---|---|
ActionsPlacement | DialogActionsPlacement?DialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the Actions render fragment appears, independently of Variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
Animation | DialogAnimation?DialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
IgnoreEscapeKey | bool?default false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
IgnoreScrimClick | bool?default false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
MaskContent | bool? | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
NoCloseButton | bool?default false | Hides the built-in close button in the full-screen variant's headline. Set it alongside IgnoreScrimClick and IgnoreEscapeKey when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
NoFocusTrap | bool?default false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
Open | bool?default false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
ReturnValue | string? | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The ReturnValue attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
ScrollIndicator | ScrollIndicator?ScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
Type | string? | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
Variant | DialogVariant?DialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Render fragments
| Parameter | Type | Description |
|---|---|---|
Actions | RenderFragment? | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
Content | RenderFragment? | Main scrollable content area |
Headline | RenderFragment? | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
Icon | RenderFragment? | An icon above the headline, in the basic variant only. Hidden from screen readers. |
Event callbacks
| Parameter | Type | Description |
|---|---|---|
OnBeforeToggle | EventCallback<ToggleEventArgs> | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
OnToggle | EventCallback<ToggleEventArgs> | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
OnCancel | EventCallback | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that IgnoreScrimClick or IgnoreEscapeKey turns off. It is cancelable. |
Inputs
| Input | Type | Description |
|---|---|---|
actionsPlacement | DialogActionsPlacementTypeDialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the actions slot appears, independently of variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
animation | DialogAnimationTypeDialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
ignoreEscapeKey | booleandefault false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
ignoreScrimClick | booleandefault false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
maskContent | boolean | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
noCloseButton | booleandefault false | Hides the built-in close button in the full-screen variant's headline. Set it alongside ignoreScrimClick and ignoreEscapeKey when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
noFocusTrap | booleandefault false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
open | booleandefault false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
returnValue | string | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The returnValue attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
scrollIndicator | ScrollIndicatorTypeScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
type | string | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
variant | DialogVariantTypeDialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Content projection
| Content | Description |
|---|---|
an element with slot="icon" | An icon above the headline, in the basic variant only. Hidden from screen readers. |
an element with slot="headline" | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
an element with slot="content" | Main scrollable content area |
an element with slot="actions" | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
Outputs
| Output | Event | Description |
|---|---|---|
cwBeforeToggle | ToggleEvent | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
cwToggle | ToggleEvent | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
cwCancel | Event | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that ignoreScrimClick or ignoreEscapeKey turns off. It is cancelable. |
Props
| Prop | Type | Description |
|---|---|---|
actionsPlacement | DialogActionsPlacementTypeDialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the actions slot appears, independently of variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
animation | DialogAnimationTypeDialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
ignoreEscapeKey | booleandefault false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
ignoreScrimClick | booleandefault false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
maskContent | boolean | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
noCloseButton | booleandefault false | Hides the built-in close button in the full-screen variant's headline. Set it alongside ignoreScrimClick and ignoreEscapeKey when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
noFocusTrap | booleandefault false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
open | booleandefault false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
returnValue | string | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The returnValue attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
scrollIndicator | ScrollIndicatorTypeScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
type | string | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
variant | DialogVariantTypeDialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Slots
| Slot | Description |
|---|---|
actions | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
content | Main scrollable content area |
headline | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
icon | An icon above the headline, in the basic variant only. Hidden from screen readers. |
Events
| Event | Type | Description |
|---|---|---|
beforeToggle | ToggleEvent | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
toggle | ToggleEvent | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
cancel | Event | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that ignoreScrimClick or ignoreEscapeKey turns off. It is cancelable. |
Props
| Prop | Type | Description |
|---|---|---|
actionsPlacement | DialogActionsPlacementTypeDialogActionsPlacement.Auto, .Bottom, .Headlinedefault DialogActionsPlacement.Auto | Where the actionsSnippet snippet appears, independently of variant. auto puts it in the headline bar for full-screen and in the footer row for basic. See Actions placement. |
animation | DialogAnimationTypeDialogAnimation.Fade, .None, .Slidedefault DialogAnimation.Fade, from the style configuration | Sets how the dialog animates open and closed. See Animation. |
ignoreEscapeKey | booleandefault false | If set to true, pressing the Escape key will not close the dialog. See Dismissing. |
ignoreScrimClick | booleandefault false | If set to true, clicking on the scrim (backdrop) will not close the dialog. See Dismissing. |
maskContent | boolean | Clips the content to the component's shape, so anything that extends past a rounded corner is cut off. |
noCloseButton | booleandefault false | Hides the built-in close button in the full-screen variant's headline. Set it alongside ignoreScrimClick and ignoreEscapeKey when the application owns every exit path — the dialog then cannot be dismissed except through content the host supplies itself. See Variants, Dismissing. |
noFocusTrap | booleandefault false | Lets Tab leave the dialog: pressing Tab on its last focusable element moves focus out to the browser, such as the address bar. Keeping focus inside is recommended for accessibility, so turn this on only when the dialog is more accessible without it. |
open | booleandefault false | Opens the dialog when set to true and closes it when set to false. Returns to false whenever the dialog closes, including by Escape or a scrim click, and when a beforetoggle listener cancels the opening. See Opening and closing. |
returnValue | string | The dialog's return value, usually naming the button that closed it. Set by close(value) or by the submit button's value in a <form method="dialog">; unchanged by Escape, a scrim click or the close button. The returnValue attribute presets it, which is the value a bare close() adopts.See MDN: HTMLDialogElement.returnValue. See Opening and closing, Forms. |
scrollIndicator | ScrollIndicatorTypeScrollIndicator.Divider, .None, .Shadowdefault ScrollIndicator.Shadow, from the style configuration | Marks the top and bottom edges of the content while it can scroll further. The content scrolls vertically only. See Scroll indicator. |
type | string | The type of dialog for accessibility. Set this to alert to announce a dialog as an alert dialog. See Alert dialogs. |
variant | DialogVariantTypeDialogVariant.Basic, .FullScreendefault DialogVariant.Basic | Sets how the dialog is laid out. Use basic for standard dialogs, full-screen for complex forms on mobile. See Variants. |
Snippets
| Snippet | Description |
|---|---|
iconSnippet | An icon above the headline, in the basic variant only. Hidden from screen readers. |
headlineSnippet | The dialog's title, which screen readers announce as its name. Without a headline, set aria-label. |
contentSnippet | Main scrollable content area |
actionsSnippet | The dialog's action buttons, in the footer or, for full-screen or actions-placement="headline", the headline bar. |
Events
| Prop | Type | Description |
|---|---|---|
onBeforeToggle | ToggleEvent | Before the opening or closing animation starts. Cancelable: calling preventDefault() leaves the dialog as it is. newState is "open" or "closed". It bubbles, is composed, and is cancelable. |
onToggle | ToggleEvent | After the opening or closing animation completes. newState is "open" or "closed". It bubbles and is composed. |
onCancel | Event | Fires when a scrim click or the Escape key dismisses the dialog. Cancel it to keep the dialog open. Not fired for a route that ignoreScrimClick or ignoreEscapeKey turns off. It is cancelable. |
Each attribute value has its own tokens; a cell shows its token's value, and selecting the cell shows the token's fallback path, with each name and value ready to copy. For example, the basic column's container-color row is --ct-dialog-basic-container-color, which defaults to --ct-sys-color-surface-container-high.
Variant
| Name | basic | full-screen |
|---|---|---|
container-color | --ct-sys-color-surface-container-high --ct-dialog-basic-container-color | --ct-sys-color-surface-container-high --ct-dialog-full-screen-container-color |
elevation | 3 --ct-dialog-basic-elevation | — |
headline-color | --ct-sys-color-on-surface --ct-dialog-basic-headline-color | — |
headline-font | --ct-sys-typescale-headline-small-font --ct-dialog-basic-headline-font | --ct-sys-typescale-headline-large-font --ct-dialog-full-screen-headline-font |
headline-line-height | --ct-sys-typescale-headline-small-line-height --ct-dialog-basic-headline-line-height | --ct-sys-typescale-headline-large-line-height --ct-dialog-full-screen-headline-line-height |
headline-size | --ct-sys-typescale-headline-small-size --ct-dialog-basic-headline-size | --ct-sys-typescale-headline-large-size --ct-dialog-full-screen-headline-size |
headline-tracking | --ct-sys-typescale-headline-small-tracking --ct-dialog-basic-headline-tracking | --ct-sys-typescale-headline-large-tracking --ct-dialog-full-screen-headline-tracking |
headline-weight | --ct-sys-typescale-headline-small-weight --ct-dialog-basic-headline-weight | --ct-sys-typescale-headline-large-weight --ct-dialog-full-screen-headline-weight |
height | fit-content --ct-dialog-basic-height | — |
icon-color | --ct-sys-color-secondary --ct-dialog-basic-icon-color | — |
icon-size | 24px --ct-dialog-basic-icon-size | — |
max-height | same as height --ct-dialog-basic-max-height | — |
max-width | same as width --ct-dialog-basic-max-width | — |
min-height | same as height --ct-dialog-basic-min-height | — |
min-width | same as width --ct-dialog-basic-min-width | — |
outline-color | transparent --ct-dialog-basic-outline-color | — |
outline-opacity | 1 --ct-dialog-basic-outline-opacity | — |
outline-width | 0px --ct-dialog-basic-outline-width | — |
scrim-blur | 0px --ct-dialog-basic-scrim-blur | — |
scrim-color | --ct-sys-color-scrim --ct-dialog-basic-scrim-color | — |
scrim-opacity | 0.32 --ct-dialog-basic-scrim-opacity | — |
supporting-text-color | --ct-sys-color-on-surface-variant --ct-dialog-basic-supporting-text-color | — |
supporting-text-font | --ct-sys-typescale-body-medium-font --ct-dialog-basic-supporting-text-font | --ct-sys-typescale-label-large-font --ct-dialog-full-screen-supporting-text-font |
supporting-text-line-height | --ct-sys-typescale-body-medium-line-height --ct-dialog-basic-supporting-text-line-height | --ct-sys-typescale-label-large-line-height --ct-dialog-full-screen-supporting-text-line-height |
supporting-text-size | --ct-sys-typescale-body-medium-size --ct-dialog-basic-supporting-text-size | --ct-sys-typescale-label-large-size --ct-dialog-full-screen-supporting-text-size |
supporting-text-tracking | --ct-sys-typescale-body-medium-tracking --ct-dialog-basic-supporting-text-tracking | --ct-sys-typescale-label-large-tracking --ct-dialog-full-screen-supporting-text-tracking |
supporting-text-weight | --ct-sys-typescale-body-medium-weight --ct-dialog-basic-supporting-text-weight | --ct-sys-typescale-label-large-weight --ct-dialog-full-screen-supporting-text-weight |
width | 48px)) --ct-dialog-basic-width | — |
Indicator
| Name | divider | shadow |
|---|---|---|
color--ct-scroll-region- | --ct-sys-color-outline-variant --ct-scroll-region-divider-color | — |
level--ct-scroll-region- | — | 3 --ct-scroll-region-shadow-level |
opacity--ct-scroll-region- | — | 0.8 --ct-scroll-region-shadow-opacity |
thickness--ct-scroll-region- | 1px --ct-scroll-region-divider-thickness | — |
thickness-block--ct-scroll-region- | — | 24px --ct-scroll-region-shadow-thickness-block |
thickness-inline--ct-scroll-region- | — | 24px --ct-scroll-region-shadow-thickness-inline |
Names and states
A dialog is announced as a modal dialog and follows the WAI-ARIA Authoring Practices: Dialog (Modal) pattern.
- The headline's text names the dialog. A dialog with no headline takes its name from an
aria-labelon it; with neither, it has no name, so give it one or the other. aria-labelis the only ARIA attribute a dialog accepts. Any otheraria-*attribute, androle, has no effect.- An alert dialog is announced with an urgent tone that a plain dialog lacks.
- The headline is announced as a level-two heading, so slot the headline as plain text in a
<div>or<span>, never as a heading element. - The
iconslot is hidden from screen readers, so an icon adds nothing to the name or description; put any meaning in the headline. - While its content overflows, the scrolling region is a named
regionlandmark. The headline names it, or else the dialog'saria-label, or else the English words "Dialog content", which are not localized. - The full-screen variant's close button is named by the localized word "Close".
- For content the reader can ignore, a Popover or a Menu suits better; see Choosing a pop-up surface.
Keyboard and focus
| Key | Action |
|---|---|
| Escape | Fires cancel, then closes the dialog; does nothing with ignore-escape-key |
| Tab | Moves focus to the next control, from the last one back to the first |
| Shift+Tab | Moves focus to the previous control, from the first one back to the last |
| The arrow keys, Page Up, Page Down, Space, Home, End | Scroll the content while its scrolling region has focus |
- On opening, focus moves to the first control in the dialog, or to the element that carries
autofocus. Putautofocuson the safest action. With nothing focusable inside, the dialog itself takes focus. - The page behind the dialog is inert while it is open, so Tab never reaches it.
removes the wrap, and Tab then moves on to the browser's own controls.no-focus-trap - Closing the dialog, by any route, returns focus to the control that had it before the dialog opened.
- While its content overflows, the scrolling region is a Tab stop, so a keyboard user can scroll it.
- The controls inside draw their own focus rings.
Pointer and touch
- A click or tap on the scrim fires
cancel, then closes the dialog, unless is set. A click inside the dialog, or inside a popover it contains, is not a scrim click.ignore-scrim-click - The only control the dialog draws itself is the full-screen variant's close button, a small icon button, whose target size against WCAG 2.5.8 (24 by 24 pixels) is the icon button's. Every other target is a control you slot in.
Display settings
- Forced colors: the dialog takes a 2-pixel outline in the system's text color, and the scrim drops its blur and keeps its opacity.
- Reduced motion: the open and close animation becomes
, whatevernone says.animation
Standards
With its defaults, a dialog meets two WCAG 2.2 success criteria:
Four more depend on how you use it:
- 2.4.3 Focus Order (A): put
autofocuson the safest action, and check that focus returns to the control that opened the dialog when it closes. - 4.1.2 Name, Role, Value (A): give the dialog a headline, or an
aria-labelwhen it has none. - 2.4.6 Headings and Labels (AA): write a headline that states the dialog's question or task.
- 1.3.1 Info and Relationships (A): slot the headline as plain text, since the dialog already makes it a heading.