Change log
Components
Dialog
- Overview
- Usage
- Accessibility
Overview
When to use
Use dialogs to focus user's attention on simple, single-step tasks, questions, or contextual messages.
When not to use
Don't use dialogs for multi-step flows or if the content is long, complex or is not important enough to interrupt the user's flow.
Principles​
Dialogs work best when they’re expected and initiated by a user’s action, like clicking a button or link.
When dialogs frequently appear for non-critical information, users may instinctively close them without reading the content. This increases the chance users dismiss important dialogs that appear later without giving them any thought.
When people enter a dialog task, they switch away from their previous context, so it is recommended to set the new context with a heading. Headings are crucial for screen reader users who cannot see the dialog appear on top of the previous context. The dialog’s heading should match or contain similar words to the button label users tapped to open it.
Dialogs shouldn’t contain large amounts of content or complex data. Keep them simple and focused. If the content is too long, it probably should have its own page.
Avoid showing multiple dialogs at the same time.
Size​
TDS has 4 standard widths for dialogs. Custom width may be defined if the content requires it.
- Small: 480px
- Medium: 640px
- Large: 800px
- Fluid: 90% width
On mobile, the width of a dialog is defined as 100% with 1-2rem margin on the left and right side.
Closing​
By default, dialogs can be closed by:
- Primary button to submit their changes, e.g., “Save” or “Done”
- “Cancel” button in the footer
- ”X” icon on top right corner
- Pressing ESC on the keyboard
- Tapping the scrim behind the dialog
If the user is required to take action (for example, after some period of inactivity, continue using the site or log out) in order to dismiss the dialog, the “X” icon should not be visible and pressing ESC or tapping the scrim should not close the dialog.
Scrolling​
Try to keep the content of the dialog simple and concise. In case it’s not at all possible, the scroll behavior can be set so that scrolling happens inside the dialog body or the whole dialog scrolls within the viewport.
Destructive actions​
Dialogs can be used to confirm destructive actions, for example deleting something permanently. In this case a danger button should be used for the destructive action.
Usage guidelines
Multiple dialogs​
Avoid showing multiple dialogs at the same time.
Don't
Use a title​
A dialog should always have a title. If a dialog is opened by a user, the title should match or contain similar words to the button label they tapped to open it.
Do
Don't
Avoid overly complex content​
Dialogs shouldn’t contain large amounts of content or complex data. Keep them simple and focused. If the content is too long, it probably should have its own page.
Do
Don't
Keyboard​
- Activating a trigger with
data-dialog-openopens the dialog and moves focus to the first focusable element inside it, or to the dialog itself if it has none. - Tab and Shift+Tab cycle through the dialog's controls. Focus cannot leave while the dialog is open; focus that lands outside, for example from browser UI, is pulled back in.
- Escape closes the dialog, as does clicking the scrim, unless the dialog is not dismissible.
- Buttons with
data-dialog-close(the secondary button and the "X") close it. - On close, focus returns to the element that opened the dialog.
Screen readers​
The dialog has role="dialog" and aria-modal="true". It is named by its title through aria-labelledby and described by its body text through aria-describedby, so both are read when it opens. The close button is named "Sulge" (closeLabel) and its icon is aria-hidden="true". With scrollType="body" the body is focusable (tabindex="0"), so keyboard users can scroll long content.
Using the example​
- The dialog
idmust be unique; the title and content ids are derived from it. - Open dialogs through a
data-dialog-openbutton, or callwindow.tdsDialog.open(id, opener)with the opener element, so focus can return to it. - Use
dismissible={false}(data-dialog-static) only when closing by accident would lose data. The dialog must then still have a visible way to close. - Keep the title short and specific. It is the first thing a screen reader user hears.
Known limits​
The primary button (data-modal-accept) does not close the dialog; your code must perform the action, close the dialog and move focus somewhere sensible. The page behind is not made inert, so hiding it from assistive technology relies on aria-modal support.