Modal
Search the component library

Modal

v1.0.0
Download UI Kit v1.9.0

Defines the standard visual style for a modal element with styles for both textual and media content.

Download UI Kit v1.9.0

Usage Guidelines

You should typically avoid modals in your designs, using the styles defined here only when necessary.

Features

  • Fully responsive, scales with browser width
  • Accessibility compliant (constrained tab scope, focus memory, etc.)
  • Styles for both textual and image content
  • Five different zoom levels for image content
  • Optional button toolbar

Text Modals

Text modals include a header with a title and standard close button. The content area can then contain either a basic text message or more structured content such as a form.

An optional button bar can present standard actions at the bottom of the modal.

The text modal uses the Static Column template and supports both sizes (480px and 800px). At smaller breakpoints both sizes shift to 100% width to prevent content from being too constrained.

Accessibility considerations

Modals must be careful to properly handle keyboard access to maintain full accessibility compliance. Specifically they must:

Capture Focus

Opening a modal should move the current keyboard focus into the first focusable element of the modal. Tabbing should only loop through items within the modal, and not escape to the underlying content.

Focus restoration

Dismissing the modal should return focus to the element that was focused when the modal was activated.

Desktop sized modal with optional button bar.

Responsive modal without the button bar.

Media Modals

This variant presents images in a stripped down and focused modal. The close button and any other tools fit in a toolbar at the top. Content is initially sized according to it’s intrinsic dimensions, with a max width/height of 90% of the space below the toolbar.

Image Zooming

Image modals optionally support zooming to 100%, 150%, 200%, 250%, and 300% levels. The image can be panned by clicking and dragging once it extends beyond the browser viewport.

Basic image modal at 100% zoom.

Zoomed to 200%.

Redlines

Text Modal

Overlay
  • Background Color: Black, 30% opacity
  • Opening the modal freezes the position of any underlying content, scrolling should only apply to the modal itself
Spacing
  • Title has 10px vertical padding, 15px horizontal padding
  • Body has 15px padding all around
Sizing
  • Uses the Static Column template in either small or large sizes
Optional Button Bar
Colors
Shadow
  • The whole modal has a dropshadow of Gray No. 1, with 7px blur and 1px spread
Typography
Icons
  • Close ‘X’ is the times icon
Dismissing
  • The text modal may be dismissing by selecting the ‘X’ icon or anywhere in the gray overlay
  • Pressing the escape key will also dismiss the modal

Responsively sized text modal with no button bar.

Media Modal

Overlay
  • Background Color: Black, 70% opacity
  • Scrolling is disabled while the modal is open
Spacing
  • Toolbar items have 10px vertical padding, 20px horizontal padding on the outside edges, 15px between items
Sizing
  • Images take on their native sizes with a maximum width/height of 90%
  • Zoomed images may extend all the way to the edge of the viewport
  • In responsive situations
Colors
Shadow
  • The image has a dropshadow of Black, with a 40px blur and 1px spread
Zooming
  • Images can be zoomed to 100%, 150%, 200%, 250%, and 300% of the original size
  • Once the image is larger than the viewport it may be panned by clicking and dragging (or just dragging on touch devices)
  • grab and grabbing css cursors should be used when panning
Icons
Dismissing
  • The media modal may be dismissed by selecting the ‘X’ icon or anywhere in the gray overlay region
  • Pressing the escape key will also dismiss the modal

Accessibility guidelines

Follow these rules and guidelines for ensuring modals behave properly when used with assistive technology.

Modals, being a single-context item (they do not coexist with any existing page, but act as though they are their own page), will need the following attributes and settings:

The dialog body itself (usually a div) needs role="dialog" and when the user opens the dialog they ought to get the “name” of it as well, so inside is usually a heading (and it can be an h1 because it’s its own context) with an id. Remember id’s must be unique to the whole HTML document and must start with a _ or a letter! The dialog div then additionally needs aria-labelledby=" the id of that heading ".

For a text-only dialog, where the modal is mostly just explaining stuff with perhaps an additional “ok” button, it’s possible/encouraged to throw an id on the p element holding that text as well and on the dialog div add aria-describedby=" id of that p element ".

Example of non-text modal code:

<div role="dialog" aria-labelledby="f123">
  <button data-foo="close">
    <i class="pe-icon--times" aria-hidden="true"></i>
    <span class="pe-sr-only">Close dialog</span>
  </button>

  <h1 id="f123">All about foo</h1>

  ... possible form elements or interactives inside mixed with text...
</div>

Example of a more text-only dialog:

<div role="dialog" aria-labelledby="q456" aria-describedby="p233">
  <button data-foo="close">
    <i class="pe-icon--times" aria-hidden="true"></i>
    <span class="pe-sr-only">Close dialog</span>
  </button>

  <h1 id="q456">Zomg</h1>

  <p id="p233">Logging in requires you first contact someone from the FooBar office</p>

  <a href="/contact">Contact the FooBar office</a>
</div>

Modals should always have a close button for touchscreen accessibility, but also listen for ESC to close and bring the focus back to the modal trigger. Focus cycles through the modal so long as it is open.

Additionally, if the modal is, source-wise, not inside the page content, then we can prevent a nonvisual user accidentally reading out of the dialog using aria-hidden. Be careful using aria-hidden and make certain it is set to “false” (or removed entirely) when the modal is closed!

When modal is not open:

<body>
  <div class="page_container">
    everything on the visible page is here!
  </div>

  <div role="dialog" aria-labelledby="f123" style="display:none;">
    ...
  </div>
</body>

When modal is open:

<body>
  <div class="page_container" aria-hidden="true">
    This page is not visible to AT!
  </div>

  <div role="dialog" aria-labelledby="f123">
    ...
  </div>
</body>

Only mess around with aria-hidden on the page if you have a structure like this. If the modal div is inside the main page content div, aria-hidden should not be used, for it will affect all children including the modal itself. AT users would basically get a blank page.

Changelog

1.0.0

Initial version