#Modals

Modals are CSS-powered prompts designed for any site.

#Structure

A modal comprises of these classes:

  • modal - the darkened translucent background around modal-content
    • modal-content - the main dialog itself.
      • modal-header - header or title bar of the dialog.
      • modal-body - main contents of the dialog.
      • modal-footer - bottom portion of dialog.

#Basic

There is quite a lot of flexibility when it comes to building your modal dialog. Typically, the modal-header consists of some title and a close button, the modal-body has whatever content you want, and the modal-footer consists of buttons to act on a prompt.

Opening a Modal

To open a modal, a link must be used with the href set to be the id of the modal. For example, if I create a modal with id test-modal, then the href of the link to open the modal should be set to #test-modal.

<div class="modal" id="test-modal">
    <!-- Modal stuff -->
</div>

<a href="#test-modal">Open Modal</a>

Close Button Creation/Behavior

The close button can be created using the btn-close class, but the examples shown here, we will be using a FontAwesome glyph wrapped with a link.

<div class="modal" id="test-modal">
    <div class="modal-header">
        <a href="#anchor-to-background" class="u-pull-right" aria-label="Close">
            <span class="icon">
                <i class="fa-wrapper fa fa-times></i>
            </span>
        </a>
    </div>
</div>

Notice that the close link must be wrapped by an anchor tag containing an href to some HTML element. The value you put in this href will alter the close behavior of the modal dialog.

Return to Specific Div

<a href="#TAG-OUTSIDE" class="modal-overlay close-btn" aria-label="Close"></a>

Return to Top

<a href="!#" class="modal-overlay close-btn" aria-label="Close"></a>

Keep Scroll Position

<a href="#NON-EXISTANT-DIV" class="modal-overlay close-btn" aria-label="Close"></a>

Below is an example of a basic modal dialog.

<div class="modal modal-animated--zoom-in" id="basic-modal">
    <a href="#searchModalDialog" class="modal-overlay close-btn" aria-label="Close"></a>
    <div class="modal-content" role="document">
        <div class="modal-header"><a href="#components" class="u-pull-right" aria-label="Close"><span class="icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="times" class="svg-inline--fa fa-times fa-w-11 fa-wrapper" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512"><path fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"></path></svg></span></a>
            <div class="modal-title">Invite</div>
        </div>
        <div class="modal-body">
            <div class="r">
                <h3 class="font-alt font-light u-text-center">Invite people to project</h3></div>
            <div class="space"></div>
            <div class="input-control">
                <input type="text" class="input-contains-icon" placeholder="Search for team members"><span class="icon"></div>
            <div class="divider"></div>
            <div class="my-1">
                <div class="tile tile--center py-1 px-2 my-1" style="box-shadow: rgba(0, 0, 0, 0.06) 0px 3px 6px, rgba(0, 0, 0, 0.03) 0px 3px 6px;">
                    <div class="tile__icon">
                        <figure class="avatar bg-teal-400" data-text="Jn"></figure>
                    </div>
                    <div class="tile__container">
                        <p class="tile__title m-0">John Newman</p>
                        <p class="tile__subtitle m-0">jnewman@gmail.com</p>
                    </div>
                    <div class="tile__buttons">
                        <button class="btn-success btn-small uppercase"><span class="icon"></span></button>
                    </div>
                </div>
                <div class="tile tile--center py-1 px-2 my-1" style="box-shadow: rgba(0, 0, 0, 0.06) 0px 3px 6px, rgba(0, 0, 0, 0.03) 0px 3px 6px;">
                    <div class="tile__icon">
                        <figure class="avatar bg-teal-500" data-text="Fw"></figure>
                    </div>
                    <div class="tile__container">
                        <p class="tile__title m-0">Franklin Watson</p>
                        <p class="tile__subtitle m-0">fwatsonm@gmail.com</p>
                    </div>
                    <div class="tile__buttons">
                        <button class="btn-success btn-small uppercase"><span class="icon"></span></button>
                    </div>
                </div>
                <div class="tile tile--center py-1 px-2 my-1" style="box-shadow: rgba(0, 0, 0, 0.06) 0px 3px 6px, rgba(0, 0, 0, 0.03) 0px 3px 6px;">
                    <div class="tile__icon">
                        <figure class="avatar bg-teal-600" data-text="Cr"></figure>
                    </div>
                    <div class="tile__container">
                        <p class="tile__title m-0">Cornelia Roberts</p>
                        <p class="tile__subtitle m-0">croberts@outlook.com</p>
                    </div>
                    <div class="tile__buttons">
                        <button class="btn-danger btn-small uppercase"><span class="icon"></span></button>
                    </div>
                </div>
                <div class="tile tile--center py-1 px-2 my-1" style="box-shadow: rgba(0, 0, 0, 0.06) 0px 3px 6px, rgba(0, 0, 0, 0.03) 0px 3px 6px;">
                    <div class="tile__icon">
                        <figure class="avatar bg-teal-700" data-text="Da"></figure>
                    </div>
                    <div class="tile__container">
                        <p class="tile__title m-0">Dominic Alvarado</p>
                        <p class="tile__subtitle m-0">dalvarado@yahoo.com</p>
                    </div>
                    <div class="tile__buttons">
                        <button class="btn-success btn-small uppercase"><span class="icon"></span></button>
                    </div>
                </div>
                <div class="tile tile--center py-1 px-2 my-1" style="box-shadow: rgba(0, 0, 0, 0.06) 0px 3px 6px, rgba(0, 0, 0, 0.03) 0px 3px 6px;">
                    <div class="tile__icon">
                        <figure class="avatar bg-teal-800" data-text="Sl"></figure>
                    </div>
                    <div class="tile__container">
                        <p class="tile__title m-0">Stanley Lim</p>
                        <p class="tile__subtitle m-0">slim@stanleylim.me</p>
                    </div>
                    <div class="tile__buttons">
                        <button class="btn-success btn-small uppercase"><span class="icon"></span></button>
                    </div>
                </div>
            </div>
        </div>
        <div class="modal-footer">
            <div class="form-section u-text-right">
                <a href="#components">
                    <button class="btn btn-small u-inline-block">Cancel</button>
                </a>
                <a href="#components">
                    <button class="btn-info btn-small u-inline-block">Confirm</button>
                </a>
            </div>
        </div>
    </div>
</div>

#Sizes

Modals come in 3 sizes: modal-small, normal, and modal-large. Append these classes to modal to set the size.

#Animations

Modals have 3 animations: modal-animated--dropdown, modal-animated--zoom-in, and modal-animated--zoom-out. Append these classes to modal to set the animation mode.

#Accessibility

To be complaint with WAI-ARIA Best Practices, you can easily include this snippet of JavaScript to close all dialogs when hitting the escape key.

document.addEventListener('keyup', function(e) {
    if(e.key === "Escape") {
        const modals = document.querySelectorAll('.modal-overlay');
        for (const modal of modals) {
            modal.click();
        }
    }
});