When the dialog opens, the dialog container receives the focus. This is why it is important it has a
That is unless there is a form control within the dialog with the
autofocus HTML attribute, as per the specification. In that case, that element will receive the focus when the dialog opens instead of the dialog container. The focus trap (mentioned below) is not impacted by this whatsoever.
The focus is being “trapped” within the dialog: pressing TAB while focusing the last element will move the focus to the first, and pressing SHIFT + TAB while focusing the first element will move the focus to the last. Note that the dialog container does not belong to that focus trap since it has
It is worth mentioning that the way focusable elements are queried to handle the first and last ones as mentioned above is not completely bulletproof. For instance, it does not consider
<embed> elements and
<details> element without any child
<summary> as focusable while it technically should. It also shows some inconsistencies with
<iframe> elements when first or last focusable element.
When the dialog closes, the element which was previously focused before opening the dialog receives the focus back again — typically the dialog opener that was interacted with.
The script does not move the focus back within the dialog if the focused element lives within an element with the
data-a11y-dialog-ignore-focus-trap attribute (with 1’s, not L’s). This is an escape hatch for advanced integrations with other libraries such as popper.js, where some content technically lives outside of the dialog itself (similar to a nested dialog for instance).
Use this escape hatch with caution as this can severely damage screen-reader users’ experience.