Skip to contentAsheeUIAsheeUI

Focus and dismissal

What an overlay owes the page behind it, where focus goes, what it covers, and how it closes.

An overlay is a promise: the page behind it stops, the reader is somewhere else for a moment, and when it closes they are put back exactly where they were. The three components here keep that promise in different shapes, and the shape is what you choose between.

The three questions

Every overlay answers the same three, in this order:

  1. Where does focus go? Into the layer, on something the reader can act on.
  2. What does it cover? A portal outside the page's own stacking context, and a scroll lock so the page behind does not move under the reader's finger.
  3. How does it close? Escape, a backdrop press, or a control inside it, and each of those is a decision rather than a default to forget.

Layers: Modal and Drawer

These two are the same contract in two positions, and both state it in the same terms:

  • Focus moves in and cannot leave. The layer traps focus while it is open, so tabbing cycles inside it rather than escaping into the page the reader cannot see.
  • Focus comes back. Closing returns it to whatever held it before the layer opened. That is the part that is invisible when it works and infuriating when it does not.
  • There is a way out that needs no pointer. The component draws a close control of its own, in the top-right corner and first in the tab order, named by closeLabel. It is there whether or not the two dismissal switches are on, so a keyboard reader never depends on a backdrop they cannot press.
  • A layer with no onClose is not allowed to hold the page. Without a close handler the layer is presented non-modally, no scroll lock, no focus trap, no aria-modal, and warns, because a layer that cannot leave must not trap the reader.
  • The page behind stops scrolling for as long as the layer is open, so a long page does not shift under a short dialog.
  • It renders in a portal, outside the page's own stacking context, so no ancestor's overflow: hidden or transform can clip or re-stack it.
  • The dialog element is the labelled one. The component gives the layer role="dialog"-style semantics; the name is the consumer's, through aria-label or aria-labelledby. A dialog with no name is announced as "dialog" and nothing else.

A drawer is the same layer anchored to an edge instead of the middle of the viewport, which is what a panel of details, filters or navigation wants. Nothing about focus, scroll or dismissal changes.

Dismissal is two switches, not one

Both layers spell the pair the same way: closeOnBackdropClick and closeOnEscape, both registered true. The drawer's older closeOnOverlayClick and closeOnEsc still work as deprecated aliases, so either name configures it, but new code should use the shared pair.

Backdrop press and Escape are not the same kind of gesture: Escape is a reader asking to cancel; a backdrop press is a mis-aimed click as often as it is a decision. Turn the backdrop off for anything the reader has typed into, losing a half-written form to a stray click is the mistake those two switches exist to prevent. Escape is offered only to the topmost layer, through a shared stack, so a modal opened over a drawer closes alone and one press never takes away two things.

Tooltips are not layers

A tooltip is the opposite of a layer, and confusing them causes real damage:

Layer Tooltip
Takes focus and traps it Never takes focus
Opens by an explicit state (isOpen) Opens on hover, or on focus when the trigger is itself focusable, the component asks for an element, and a text child is rejected by the type
Announces a dialog Describes its trigger, it is read with the control, not instead of it
Closes on Escape and a backdrop press Closes when the reader moves away

Because the trigger is described rather than replaced, a tooltip may hold only what a reader would have heard anyway: wording, a shortcut, a unit. Never put a control inside a tooltip, it cannot be reached, because moving the pointer towards it dismisses it, and it cannot be tabbed to, because the tooltip never holds focus. Interactive content belongs in a menu, a popover or a dialog.

A tooltip is also always a supplement: the control it describes must still make sense without it, because a touch reader may never see it at all.

The rule both share

Nothing opens without a way out that does not depend on a pointer. A layer needs Escape or a visible control; a tooltip needs the reader to be able to move away. An overlay that can only be dismissed by pressing the thing that dismisses it, somewhere the reader cannot reach, is a trap in the other sense of the word.

See Announcements for what these say when they open, and Accessibility for the keyboard model underneath.