Modals

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.

Help wanted! Each of our components will eventually ship with default JavaScript interactivity. We could use your help writing that JavaScript. To get started, check out the spec.

For examples of some JavaScript that’s been shipped, see our sortable table component or our expandable control.

It can be tempting to hack together a quick fix in jQuery for displaying a Modal for your feature, but it may be just as much work as doing it properly as a Stimulus component—and this way every developer at Stack Overflow now has Modals at their disposal.

Examples

<aside class="s-modal js-modal-overlay js-modal-close" id="modal-base" tabindex="-1" role="dialog" aria-labelledby="modal-title" aria-describedby="modal-description" aria-hidden="true">
    <div class="s-modal--dialog js-modal-dialog" role="document">
        <h1 class="s-modal--header" id="modal-title"></h1>
        <p class="s-modal--body" id="modal-description"></p>
        <div class="grid gs8 gsx s-modal--footer">
            <button class="grid--cell s-btn s-btn__primary js-modal-primary-btn" type="button"></button>
            <button class="grid--cell s-btn js-modal-cancel-btn" type="button"></button>
        </div>
        <a class="s-modal--close s-btn s-btn__muted js-modal-close" href="#" aria-label="Close">
            @Svg.ClearSm
        </a>
    </div>
</aside>
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)

Danger state

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 .has-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.

<aside class="s-modal has-danger js-modal-overlay js-modal-close" id="modal-base" tabindex="-1" role="dialog" aria-labelledby="modal-title" aria-describedby="modal-description" aria-hidden="true">
    <div class="s-modal--dialog js-modal-dialog" role="document">
        <h1 class="s-modal--header" id="modal-title"></h1>
        <p class="s-modal--body" id="modal-description"></p>
        <div class="grid gs8 gsx s-modal--footer">
            <button class="grid--cell s-btn s-btn__filled s-btn__danger js-modal-primary-btn" type="button"></button>
            <button class="grid--cell s-btn s-btn__muted js-modal-cancel-btn" type="button"></button>
        </div>
        <a class="s-modal--close s-btn s-btn__muted js-modal-close" href="#" aria-label="Close">
            @Svg.ClearSm
        </a>
    </div>
</aside>

Sizes

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:

Class Value Pixels (13px base) Pixels (15px base)
.s-modal__full 100% - 48px N/A N/A