Anatomy UI

Dialogs

Dialogs are an overarching concept that can be narrowed to modals and popovers. Additionally, a dialog element exists to abstract common patterns usually implemented with a combination of HTML, CSS, and Javascript.


Element definition

The <dialog> element is a recent introduction in HTML, intended to abstract complex but yet common patterns, mainly around positioning, visibility, and focus.1 In the past, use of the element was discouraged due to incomplete features, browser support, and mismatched expectations around accessibility, but the tide seems to be turning in favor of using <dialog> over more custom implementations.

At its most basic, using <dialog> in HTML isn’t much different than custom implementations:

<button type="button">open dialog</button>

<!-- semantically the same as <div role="dialog"> -->
<dialog>
  <h2>Title</h2>
  <p>Description</p>

  <!-- autofocus should be placed on a focusable element or the dialog itself  -->
  <button type="button" autofocus>close dialog</button>
</dialog>

Note: Do not include the tabindex attribute on <dialog> elements as they already handle focus trapping.


Modal vs modeless

The <dialog> element can act as both a modal or modeless–or non-modal–element. Using the showModal() Javascript function to open a dialog sets it as a modal, while using the show() Javascript function sets it as modeless, placing it inline within the document (with a default position style of absolute). The differences between the two are nuanced:

feature modal modeless
default position fixed absolute
includes default styles yes yes
supports the close() function yes yes
supports the ::backdrop selector yes no
disables non-dialog elements yes no
dismisses on esc yes no
sits in the top layer (unaffected by Z stacking contexts) yes no

Backdrop

When setting a dialog as a modal, the backdrop between the dialog and background elements can be styled via the ::backdrop pseudo selector.

dialog::backdrop {
}

Animations

Dialogs don’t animate by default, but they can configured via the animate CSS property. Transitions won’t work as the dialog isn’t visible to start, but due to the way they are opened and closed, an animation will re-run on every appearance. Both the dialog and ::backdrop selector can be animated, but be aware that this only works when opening the dialog.

For more control over animations, descendant elements can be used alongside more Javascript. Or you can disregard the <dialog> element altogether in favor of <div role=\"dialog\">


Roles

The dialog role can be applied to a regular <div> to signal to the DOM that the current element should behave like a regular dialog:

<!-- semantically the same as using <dialog> -->
<div role="dialog"></div>

However, this role will not provide any of the features the built-in <dialog> includes, like a backdrop, focus trapping, or special z-index stacking.


Alerts

For dialogs that show important messages and require a confirmation or cancel action, use the alertdialog role:

<div role="alertdialog">
  <button>cancel</button>
  <button>confirm</button>
</div>

Alert dialogs are useful for situations such as confirming a destructive action or when an error requires user input to address it, and they are always considered modals since a blocking action is required.2