The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

A pop-up window used to request information or feedback from the user, confirm a decision, or provide additional context about a function or feature.

Modals are used to request information or feedback from the user, confirm a decision, or less frequently to provide additional context about a function or feature.

Usage

When to use

  • When requesting an urgent or immediate response from the user.
  • As a confirmation when performing a destructive action or action that will impact other areas of the application.
  • For non-frequent tasks that can be interacted with quickly.

When not to use

  • When a user action is not immediately required.
  • In place of an alert, instead use a Toast or other alert type.
  • For complex editing, long forms, and experiences with a high level of detail. In these cases, the task or function should exist at the page level.

Size

Small

Small Modal

Modal content

Medium

Small Modal

Modal content

Large

Large Modal

Modal content

Best practices

  • Use a Modal size that best accounts for the complexity of the content and intended speed of interaction.
  • The medium size accounts for the majority of scenarios and is the default recommended size.

Color

Neutral

Neutral Modal

Modal content

Neutral should be used for the majority of Modal instances and is best used in circumstances where the outcome of the Modal’s function doesn’t change or alter areas of the application that aren’t directly tied to the current context of the user. Common usage examples include:

  • functions for creating, editing, or updating objects
  • simple requests of information from the user
  • quick confirmations of actions taken by the user.

Warning

Warning Modal

Modal content

Warning indicates that the Modal’s action may impact a setting, item, or object and is used to message the potential impact while confirming that the user wants to continue.

This action may impact areas of the application outside of the scope of the current feature or function, but can also be tied to the context that the user is currently in. Common examples include:

  • disabling or enabling an application-wide setting or feature
  • archiving an item that can be recovered
  • changing a setting that may require the user to re-authenticate or perform an action again.

Critical

Critical Modal

Modal content

critical is used to indicate a destructive action that is irreversible and will impact other settings, items, or objects within the current feature or in other areas of the application. Common examples include:

  • deleting an item or object that cannot be recovered
  • modifying a setting that cannot be changed or reversed in the future
  • alerting the user of unsaved changes that will be discarded.

Body type

Modal body types

  • The default body type is meant for simple text-based content and could be used for a quick confirmation of an action or disclosure of information.
  • The custom body type is suitable for the majority of use cases when collecting information or feedback from the user. It can accept any custom component and nested components by swapping out the placeholder instance with a local component or relevant HDS component.

Actions

General best practices

  • The only property that should be changed in the actions within the footer is the text property, except in the case of a critical or destructive function (in which the button should reflect the destructive action).
  • Action buttons should remain consistent with the variants defined in the number of actions in the footer; primary, secondary, and tertiary, in that order.
  • Action buttons should not use an icon within the context of the Modal. In the context of a Modal the function should be apparent through the use of other elements like title, tagline, and icon.
  • Most Modals should use two inverse actions; or two actions that perform opposite functions (i.e. “ok/cancel”, “yes/no”).

One action

Two actions

Three actions

Tertiary best practices

  • If a tertiary action is necessary it should not be grouped with the button set of primary and secondary actions, as button grouping should be determined by functionality.
  • Common examples of tertiary actions include:
    • Linking to external documentation
    • Linking to another related area or function within the application; best used to help the user better understand or collect the information needed to interact with the Modal.

Action content guidelines

Modal actions should be concise and not written as sentences

  • Most of the time one or two words are adequate for an action, air on the side of simplicity whenever possible.
  • The expected function of the action (positive/negative, confirm/cancel) is reinforced by the button type and visual language expressed within.
  • Buttons in a Modal should follow the same content guidelines covered in the button component.
Do

Don’t

If using two actions within a Modal, the messages (and functions) should be inverses of each other

  • Adhering to an inverse action pattern is more pragmatic and straightforward to the user. This pattern clearly communicates the outcome and intended results of whatever action the user chooses.
  • Most Modals should have a low to medium level of complexity and promote interaction with a simple "yes/no" or "ok/cancel".
  • If the complexity of the Modal breaks this pattern, consider moving the function being performed by the Modal to its own page.

Title icon

With title icon

Title

Without title icon

Title

Usage

An icon paired with the title can help reinforce the purpose and function of the Modal while also drawing the eye to the header and title area.

Icons can be used to communicate the severity and importance of interacting with a Modal and are especially useful in a warning or critical color Modal.

The purpose and function of the Modal should not rely solely on an icon, instead the title should be explicit and pragmatic while the icon provides visual support.

Tagline

With tagline

Tagline
Title

With tagline and icon

Tagline
Title

Usage

A tagline helps the user maintain the context of the feature, function, or flow the Modal was triggered by. Since a Modal disables and obscures the main page content, adding a tagline can help the user understand the relationship between the Modal and the main page content.

The tagline should directly reference the page, function, or feature title to reinforce the relationship of the Modal to the main page content.

Even though adding a title icon and tagline can help the user better understand the function and importance of the task they are performing, both elements add visual weight which might not be suitable or necessary for all Modals.

Dismissal

The most common dismissal method for a Modal is via the dismiss button in the Modal header. This acts as a simple escape hatch for the user and helps prevent the user from getting stuck.

  • It is recommended to provide the user with a clear dismissal option in most Modal instances, most easily handled by the dismiss button.
  • A Modal lacking a dismiss action should be rare, but can be done to elevate the importance of the Modal and lower the possibility of accidental dismissal.
  • In the case of a single action, the dismiss acts as an escape hatch if the user needs to return to the main page content.
    • Depending on the information being requested a secondary action that closes or cancels the model may not perform the same function as dismissing the Modal. For example; responding “no” to a “yes/no” question is not the same as dismissing the Modal, the latter of which does not submit a response.
    • While certain experiences may only call for a single action button, most Modal instances should have a “cancel” button as a more explicit method to close the Modal.

The entry point for a Modal should be straightforward enough that if a user accidentally dismisses it, the Modal can be easily triggered again.

Dismissal actions

The following actions will dismiss or close the Modal except if isDismissDisabled is set to true in the production component:

  • Dismiss button in the Modal header
  • Clicking with a mouse outside of the Modal on the overlay
  • Hitting the escape (ESC) key on the keyboard
  • A cancel or close button in the footer can also act as a way to dismiss the Modal, but doesn’t always function in the same way (see the section on actions for more details).

Dismissal options for the Modal

If a user attempts to dismiss a Modal that contains a partially filled form or other interactive elements, ensure that the following criteria are met to promote a positive user experience:

  • The default browser notification is being triggered calling attention to a potential misstep.
  • Partially filled form data is persisted within the application to prevent duplicative work.

Note: Both of the above steps are recommendations of the HDS team, but are the responsibility of consumers to implement at the application level.

Default browser notification

Position and responsive sizing

Modal positioning

Modals should be positioned in the center of the viewport, paired with the overlay component, and on top of the main page content.

  • This is true regardless of if there is a sidebar or navigational element that persists on the page. The intention of the overlay is to sit on top of all page content, including navigation.

Mobile layout of the Modal

The Modal should hug the height of the body content and expand to a maximum height of 100% of the viewport height minus a 16px margin from the viewport edge.

  • If the body content exceeds the maximum height of the viewport, scroll will be introduced within the Modal body.
  • The header and footer are not included in the scrolling section, only the body content. These elements should always be visible for the user to more easily understand the intended function and possible actions.

As a general rule of thumb, the Modal should not be resized manually, rather select the size that best accommodates the content.

Browser support

The Hds::Modal component leverages the <dialog> element which is currently supported by all major browser vendors. To ensure support on older browser versions (for example, Safari 14 or Internet Explorer 11) we rely on a polyfill that is automatically loaded when needed.

Page scroll

When an Hds::Modal component is open, the rest of the page is disabled (via inert). However, scrolling at the page level is still available. To make it clear to the user that the underlying elements are not interactive and to avoid confusion, we recommend disabling the page scroll onOpen and enabling it back onClose (for example, by setting overflow: hidden; and overflow: auto; respectively) by applying it to the <body> element.

Positioning

As an overlaying component, the Hds::Modal requires a high value on the z-axis. We are currently setting 50 as a default value, but we recommend you review the z-index values used across your project and either adjust them accordingly or increase this value by defining an override.

Focus trap

This component uses ember-focus-trap to prevent the focus from going outside the Modal and to deactivate the Modal when clicking outside the Modal. This Ember modifier requires at least one interactive element to be present within the Modal, which is by default achieved by the dismiss button in the header.

Basic use

<Hds::Button
  @text="Open basic modal"
  @color="secondary"
  {{on "click" (fn this.activateModal "basicModalActive")}}
/>

{{#if this.basicModalActive}}
  <Hds::Modal id="basic-modal" @onClose={{fn this.deactivateModal "basicModalActive"}} as |M|>
    <M.Header>
      Modal title
    </M.Header>
    <M.Body>
      <p class="hds-typography-body-300 hds-foreground-primary">Modal content</p>
    </M.Body>
    <M.Footer as |F|>
      <Hds::Button type="button" @text="Confirm" {{on "click" F.close}} />
    </M.Footer>
  </Hds::Modal>
{{/if}}

When a modal is opened with the keyboard, the focus is automatically set to the first focusable element inside the modal, which is the "Dismiss" button. The action of this button has no effect on the system, so focusing on it helps prevent users from accidentally confirming the modal.

Form within a modal dialog

When the modal dialog contains information that might be lost on close, use a confirmation message before discarding it.

<Hds::Button
  @text="Open form modal"
  @color="secondary"
  {{on "click" (fn this.activateModal "formModalActive")}}
/>

{{#if this.formModalActive}}
  <Hds::Modal
    id="form-modal"
    @isDismissDisabled={{this.isModalDismissDisabled}}
    @onClose={{fn this.checkBeforeDeactivate "formModalActive"}}
    as |M|
  >
    <M.Header>
      Why do you want to leave the beta?
    </M.Header>
    <M.Body>
      <form {{on "change" this.markFormAsChanged}} name="leaving-beta-form">
        <Hds::Form::Select::Field autofocus @width="100%" as |F|>
          <F.Label>Select the primary reason</F.Label>
          <F.Options>
            <option></option>
          </F.Options>
        </Hds::Form::Select::Field>
        <Hds::Form::Textarea::Field @isOptional={{true}} as |F|>
          <F.Label>Your feedback</F.Label>
        </Hds::Form::Textarea::Field>
      </form>
    </M.Body>
    <M.Footer as |F|>
      <Hds::ButtonSet>
        <Hds::Button type="submit" @text="Leave Beta"
          {{on "click" (fn this.saveFormAndClose "formModalActive")}}
        />
        <Hds::Button type="button" @text="Cancel" @color="secondary" {{on "click" F.close}} />
      </Hds::ButtonSet>
    </M.Footer>
  </Hds::Modal>
{{/if}}

If a modal dialog contains interactive elements, such as a form, the initial focus should be set on the first input, which is the first focusable element within the form. This can be achieved by setting the autofocus property on the first form element.

Component API

Name
size
Type
enum
Values
  • small
  • medium (default)
  • large
Description
Sets the width of the modal.
Name
color
Type
enum
Values
  • neutral (default)
  • warning
  • critical
Description
Sets the color scheme for the modal header elements: icon, tagline, and title.
Name
onOpen
Type
function
Description
Callback function invoked when the modal is opened.
Name
onClose
Type
function
Description
Callback function invoked when the modal is closed.
Name
isDismissDisabled
Type
boolean
Values
  • false (default)
  • true
Description
Set this boolean to true if you want to prevent the modal from being closed (for instance, to avoid accidental data loss in an unsubmitted form). Make sure you communicate to users the reason why the modal is still open, and what they need to do to resolve the problem that is preventing the modal from being closed.
Name
…attributes
Description
This component supports use of ...attributes.

Contextual components

The title, the content of the modal dialog, and the actions are passed into the modal as yielded components, using the Header, Body, Footer keys.

Modal::Header

It is a container that yields its content as the title of the modal dialog.

Name
icon
Type
string
Description
Icon name.
Name
tagline
Type
string
Description
A string that helps the user maintain context when a modal dialog is open. Note: this is NOT the title text, but a small piece of text above the title text.
Name
…attributes
Description
This component supports use of ...attributes.

Modal::Body

The body of the Modal is an unstyled, generic container that yields as the main content of the modal dialog.

When the yielded content exceeds the available space, a scrollbar is introduced to the container.

This component supports use of ...attributes.

Modal::Footer

A container that yields its content as the footer of the modal dialog.

We recommend using it exclusively for actions using the ButtonSet component. If a tertiary action is presented, it will always be aligned at the end of the row.

Name
close
Type
function
Name
…attributes
Description
This component supports use of ...attributes.

Anatomy

Anatomy of a modal

Element Usage
Header
Title icon Optional
Tagline Optional
Title Required
Dismiss Required, all modals are dismissible
Body
Content Required; either default (simple text) or custom
Footer
Actions Required; either one, two, or three

Conformance

Conformant

The Modal component is conformant when used as directed.

Focus and focus order

  • When the Modal is triggered via the keyboard, focus is trapped within the Modal.
  • If there are no interactive elements within the body of the Modal the dismiss button should receive focus as the first interactive element in the DOM (document object model).
  • If there is an interactive element within the body of the Modal (like a form input or link), that element should be targeted for focus first.
  • Since a Modal is a complex pattern that can contain any combination of nested components and content, nested elements must adhere to their individual accessibility criteria.

Focus order within a simple Modal

Given the Modal is triggered via a keyboard, the dismiss button is first in the focus order since there isn’t any content within the body that is eligible to receive focus.

Simple focus within a modal

Focus order within a complex Modal

  • If the Modal body contains interactive content, the first element should receive focus first.
  • This is true regardless of how the Modal is triggered; either via a mouse click or via the keyboard.

Complex focus within a modal

Applicable WCAG Success Criteria

This section is for reference only, some descriptions have been truncated for brevity. This component intends to conform to the following WCAG Success Criteria:

  • 1.1.1 Non-text Content (Level A):
    All non-text content that is presented to the user has a text alternative that serves the equivalent purpose.
  • 1.3.1 Info and Relationships (Level A):
    Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
  • 1.3.2 Meaningful Sequence (Level A):
    When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.
  • 1.3.3 Sensory Characteristics (Level A):
    Instructions provided for understanding and operating content do not rely solely on sensory characteristics of components such as shape, color, size, visual location, orientation, or sound.
  • 1.3.5 Identify Input Purpose (Level AA):
    The purpose of each input field collecting information about the user can be programmatically determined when the input field serves a purpose identified in the Input Purposes for User Interface Components section; and the content is implemented using technologies with support for identifying the expected meaning for form input data.
  • 1.4.1 Use of Color (Level A):
    Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
  • 1.4.10 Reflow (Level AA):
    Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions.
  • 1.4.11 Non-text Contrast (Level AA):
    The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): user interface components; graphical objects.
  • 1.4.12 Text Spacing (Level AA):
    No loss of content or functionality occurs by setting all of the following and by changing no other style property: line height set to 1.5; spacing following paragraphs set to at least 2x the font size; letter-spacing set at least 0.12x of the font size, word spacing set to at least 0.16 times the font size.
  • 1.4.13 Content on Hover or Focus (Level AA):
    Where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true: dismissible, hoverable, persistent (see link).
  • 1.4.3 Minimum Contrast (Level AA):
    The visual presentation of text and images of text has a contrast ratio of at least 4.5:1
  • 1.4.4 Resize Text (Level AA):
    Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
  • 1.4.5 Images of Text (Level AA):
    This is old. Don’t do this. Use text. Also a logo is not an image of text, so that’s fine.
  • 2.1.1 Keyboard (Level A):
    All functionality of the content is operable through a keyboard interface.
  • 2.1.2 No Keyboard Trap (Level A):
    If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface.
  • 2.1.4 Character Key Shortcuts (Level A):
    If a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then it should be able to be turned off, remapped, or active only on focus.
  • 2.4.2 Page Titled (Level A):
    Web pages have titles that describe topic or purpose.
  • 2.4.3 Focus Order (Level A):
    If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.
  • 2.4.6 Headings and Labels (Level AA):
    Headings and labels describe topic or purpose.
  • 2.4.7 Focus Visible (Level AA):
    Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
  • 3.2.1 On Focus (Level A):
    When any user interface component receives focus, it does not initiate a change of context.
  • 3.2.2 On Input (Level A):
    Changing the setting of any user interface component does not automatically cause a change of context unless the user has been advised of the behavior before using the component.
  • 3.3.1 Error Identification (Level A):
    If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.
  • 3.3.2 Labels or Instructions (Level A):
    Labels or instructions are provided when content requires user input.
  • 3.3.3 Error Suggestion (Level AA):
    If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.
  • 3.3.4 Error Prevention (Legal, Financial, Data) (Level AA):
    For Web pages that cause legal commitments or financial transactions for the user to occur, that modify or delete user-controllable data in data storage systems, or that submit user test responses, at least one of the following is true: submissions are reversible, data is checked and user is provided an opportunity to correct them, a mechanism is available for reviewing, confirming and correcting the information before finalizing the submission.
  • 4.1.1 Parsing (Level A):
    In content implemented using markup languages, elements have complete start and end tags, elements are nested according to their specifications, elements do not contain duplicate attributes, and any IDs are unique.
  • 4.1.2 Name, Role, Value (Level A):
    For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.
  • 4.1.3 Status Messages (Level AA):
    In content implemented using markup languages, status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.


Support

If any accessibility issues have been found within this component, let us know by submitting an issue.