https://open-ui.org/components/popover.research.explainer/#popover-vs-dialog
A natural question that commonly arises is: what’s the difference between a “popover” and a “dialog”? There are two ways to interpret this question:
- What are the difference between these general UX patterns and words?
- What are the technical implementation differences between
<div popover>and<dialog>?
In both cases, an important distinction needs to be made between modal and non-modal (or modeless) dialogs. With a modal dialog, the rest of the page (outside the dialog) is rendered inert, so that only the contents of the dialog are interactable. Importantly, a popover is non-modal. Almost by definition, a popover is not permanent: it goes away (via light dismiss) when the user changes their attention to something else, by clicking or tabbing to something else. For these reasons, if the dialog in question needs to be modal, then the <dialog> element is the way to go.
Having said that, dialogs can also be non-modal, and popovers can be set to not light-dismiss (via popover=manual). There is a significant area of overlap between the two Web features. Some use cases that lie in this area of overlap include:
- “Toasts” or asynchronous notifications, which stay onscreen until dismissed manually or via a timer.
- Persistent UI, such as teaching-UI, that needs to stay on screen while the user interacts with the page.
- Custom components that need to “manually” control popover behavior.
Given these use cases, it’s important to call out the technical differences between a non-modal <dialog> and a <div popover=manual>:
- A
<div popover=manual>is in the top layer, so it draws on top of other content. The same is not true for a non-modal<dialog>. This is likely the most impactful difference, as it tends to be difficult to ensure that a non-modal<dialog>is painted on top of other page content. - A
<dialog>element always hasrole=dialog, while thepopoverattribute can be applied to the most-semantically-relevant HTML element, including the<dialog>element itself:<dialog popover>. - The popover API comes with some “nice to haves”:
- popovers are easy to animate both the show and hide transitions, via pure CSS. In contrast, JS is required in order to animate
dialog.close(). - popovers work with the invoking attributes (e.g.
popovertarget) to declaratively show/hide them with pure HTML. In contrast, JS is required to show/close a<dialog>. - popovers fire both a “popovershow” and a “popoverhide” event. In contrast, a
<dialog>only firescancelandclose, but no event is fired when it is shown.
- popovers are easy to animate both the show and hide transitions, via pure CSS. In contrast, JS is required in order to animate
For the above reasons, it seems clear that for use cases that need a non-modal dialog which has popover behavior, a <dialog popover> (with the most appropriate value for the popover attribute) should be preferred. Importantly, if the use case is not meant to be exposed as a “dialog”, then another (non-<dialog>) element should be used with the popover attribute, or a generic <div popover role=something> should be used with the appropriate role added.