Modals are dialog overlays that prevent the user from interacting with the rest of the website until an action is taken or the dialog is dismissed. Modals are purposefully disruptive and should be used thoughtfully and sparingly.
Classes
Class
Applies to
Description
.s-modal
N/A
Base parent container for modals
.s-modal__danger
.s-modal
Adds styling for potentially dangerous actions
.s-modal--dialog
Child of .s-modal
Creates a container that holds the modal dialog with proper padding and shadows
.s-modal--header
Child of .s-modal--dialog
Adds proper styling to the modal dialog’s header
.s-modal--body
Child of .s-modal--dialog
Adds proper styling to the modal dialog’s body text
.s-modal--footer
Child of .s-modal--dialog
Adds the desired spacing to the row of button actions.
.s-modal--close
Child of .s-modal--dialog
Used to dismiss a modal
.s-modal__full
.s-modal--dialog
Makes the .s-modal--dialog container take up as much of the screen as possible.
JavaScript
Attributes
Attribute
Applied to
Description
data-controller="s-modal"
Controller element
Wires up the element to the modal controller. This may be a .s-modal element or a wrapper element.
data-target="s-modal.modal"
.s-modal element
Wires up the element that is to be shown/hidden
data-target="s-modal.initialFocus"
Any child focusable element
Optional Designates which element to focus on modal show. If absent, defaults to the first focusable element within the modal.
data-action="s-modal#toggle"
Toggling element
Wires up the element to toggle the visibility of a modal
data-s-modal-return-element="[css selector]"
Controller element
Optional Designates the element to return focus to when the modal is closed. If left unset, focus is not altered on close.
data-s-modal-remove-when-hidden="true"
Controller element
Optional Removes the modal from the DOM entirely when it is hidden
Events
Event
Element
Description
s-modal:show
Controller element
Default preventable Fires immediately before showing the modal. Calling .preventDefault() cancels the display of the modal.
s-modal:shown
Controller element
Fires after the modal has been visually shown
s-modal:hide
Controller element
Default preventable Fires immediately before hiding the modal. Calling .preventDefault() cancels the removal of the modal.
s-modal:hidden
Controller element
Fires after the modal has been visually hidden
event.detail
Applicable events
Description
dispatcher
s-modal:*
Contains the Element that initiated the event. For instance, the button clicked to show, the element clicked outside the modal that caused it to hide, etc.
returnElement
s-modal:show, s-modal:hide
Contains the Element to return focus to on hide. If a value is set to this property inside an event listener, it will be updated on the controller as well.
Helpers
Function
Parameters
Description
Stacks.showModal
element: the element the data-controller="s-modal" attribute is on
Helper to manually show an s-modal element via external JS
Stacks.hideModal
element: the element the data-controller="s-modal" attribute is on
Helper to manually hide an s-modal element via external JS
Accessibility
Modals are designed with accessibility in mind by default. When a modal is open, navigation with the keyboard will be constrained to only those elements within the modal.
To ensure maximum compatibility, all a tags must have href attributes and any default focusable items you don’t want focusable must have their tabindex set to -1.
Item
Applied to
Description
aria-describedby="[id]"
.s-modal
Supply the modal’s summary copy id. Assistive technologies (such as screen readers) use this to attribute to associate static text with a widget, element groups, headings, definitions, etc. (Source)
aria-hidden="[state]"
.s-modal
Informs assistive technologies (such as screen readers) if they should ignore the element. This should not be confused with the HTML5 hidden attribute which tells the browser to not display an element. (Source)
aria-label="[text]"
.s-modal--close
Labels the element for assistive technologies (such as screen readers). (Source)
aria-labelledby="[id]"
.s-modal
Supply the modal’s title id here. Assistive technologies (such as screen readers) use this to attribute to catalog the document objects correctly. (Source)
role="dialog"
.s-modal
Identifies dialog elements for assistive technologies (Source)
role="document"
.s-modal--dialog
Helps assistive technologies to switch their reading mode from the larger document to a focused dialog window. (Source)
Examples
You can wire up a modal along with the corresponding button by wrapping both in a s-modal controller and attaching the corresponding data-* attributes. Make sure to set data-s-modal-return-element if you want your button to refocus on close.
Alternatively, you can also use the built in helper to display a modal straight from your JS file. This is useful for the times when your modal markup can’t live next to your button or if it is generated dynamically (e.g. from an AJAX call).
Not every modal is sunshine and rainbows. Sometimes there are potentially drastic things that could happen by hitting a confirm button in a modal—such as deleting an account. In moments like this, add the .s-modal__danger class to .s-modal. Additionally, you should switch the buttons to .s-btn__danger.s-btn__filled, since the main call to action will be destructive.
Most modal dialogs look good by default, but may need some combination of .ws[x] or .wmx[x] classes applied to .s-modal--dialog. Additionally, the following class is available for modals: