Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

closedby attribute doesn't work when dialog uses the popover API #11105

Open
o-t-w opened this issue Mar 5, 2025 · 3 comments
Open

closedby attribute doesn't work when dialog uses the popover API #11105

o-t-w opened this issue Mar 5, 2025 · 3 comments
Assignees
Labels
topic: dialog The <dialog> element topic: popover The popover attribute and friends

Comments

@o-t-w
Copy link

o-t-w commented Mar 5, 2025

What is the issue with the HTML Standard?

Non-modal dialogs should be able to make use of the closedby attribute.

A dialog using the .show() method or open attribute does not make use of the top layer, which can lead to issues with z-index. For that reason, combining the dialog element with the popover attribute is probably a better approach for non-modal dialogs (There's even an open issue with many thumbs ups for deprecating dialog.show(). There is no invoker command to open a non-modal dialog precisely because combining show-popover with <dialog> is considered a better approach for this use case).

For a non-modal dialog, I do not want light dismiss when the user clicks the page, so I would use popover="manual". I do want the escape key to close the dialog, as this is an expected behaviour for dialogs. Because I have opened the dialog via .showPopover() rather than show() or showModal(), closing via the escape key is not default behaviour. Currently I would need to manually add this behaviour with JavaScript via a CloseWatcher. This is fairly trivial but I do think the current behaviour will trip people up.

The closedby attribute is a way for developers to state via HTML how a dialog can be closed. The way it is currently specced, it does not work when the dialog has been shown via .showPopover(). This is unfortunate. Not only is it a simpler approach than using script, it represents a consistent way to solve this issue. Seeing as closedby is a very explicit way to specify what behaviour is wanted, it should override the popover behaviour.

The closedby attribute is for dialogs, and regardless of how it gets shown, if an element is a dialog, the developer expectation will be that they can use closedby. The following should be specced to work:

<dialog closedby="closerequest" popover="manual">
A non-modal popover dialog in the top layer.
</dialog>
@annevk annevk added topic: dialog The <dialog> element topic: popover The popover attribute and friends labels Mar 6, 2025
@mfreed7
Copy link
Contributor

mfreed7 commented Mar 6, 2025

For a non-modal dialog, I do not want light dismiss when the user clicks the page,

Can you say more about why? From a user's point of view, I think there's something of an expectation that a <dialog popover> is light dismissible. It's by definition a lightweight piece of UI that doesn't require immediate attention, so clicking elsewhere should close it. If it isn't light dismissible, then perhaps it actually should be a modal dialog. So I'd just like to understand more.

@o-t-w
Copy link
Author

o-t-w commented Mar 7, 2025

A UX debate can be had for either approach, but I think it's best to let developers/designers decide based on the specific context.

For a non-modal dialog, the user may be clicking outside of the dialog because they want to interact with the page, not because they want to close the dialog (whereas pressing the escape key is explicitly an action to close a dialog).

The whole point of a non-modal dialog is that the page remains interactive, allowing users to continue their activity with the option to interact with the modal when they choose to.

If it isn't light dismissible, then perhaps it actually should be a modal dialog.

I think there's a middle ground where a dialog is somewhat important/useful but does not require immediate attention, so the disruption of a modal dialog would be best avoided. Just because a dialog is non-modal doesn't mean it is frivolous. A vital error notification might be implemented as a non-modal dialog, for example. Important notifications might be accidentally dismissed before the user has a chance to read them, because the user was busy interacting with the page, which will instantly close the notification. (see this example from the Nord design system). What if the user wants to interact with the dialog, but is in the middle of another activity they want to complete first? A menu or a tooltip can be easily reopened by the user, so light dismiss functionality makes sense. The same is not always true of dialogs, which is why I feel that light-dismiss makes it too easy to close a dialog. There may be no way for the user to reopen that dialog again, so I'd want the close action to be purposeful rather than an accidental unknowing byproduct of clicking the page. Modeless dialogs are often small and confined to the bottom corner of the screen so they aren't disruptive or distracting, so there's no great benefit to dismissing them so effortlessly.

For another use-case, see the Gmail example discussed by NN Group:

In situations where the task is not critical, a nonmodal dialog might be appropriate. Nonmodal dialogs are less offensive than modal ones because they allow users to continue their activity and ignore them if they are irrelevant... Nonmodal windows are useful when users need to quickly switch between modes in order to access certain information. For example, Google Mail uses nonmodal windows as the default method for composing new email messages. Users can continue working with this window open, minimize the composed email without losing it (or optionally, maximize it into a modal window). This separate view allows users to locate older emails or additional information that might be helpful for composing the current email.

Some example non-modal dialogs in the wild that do not use light-dismiss:

IBM Carbon design system:

"Use when a user needs to compare or refer to information in the main page alongside the modal. users can interact with the non-modal content and the on-page content simultaneously."

Fluent UI docs:

"Since non-modal dialogs allow interaction with the content behind them, they can’t be dismissed by selecting an area outside of the dialog."

ServiceNow docs:

"A modeless dialog is a window that appears in a workspace as an overlay on top of the main window content. This overlay enables users to interact with the window content and the overlay content at the same time."

Plenty of cookie consents are non-modal and allow interaction with the page. See the Google example below or cookie dialog on the Smashing Mag site.

image

Non-modal dialogs that use the .show() method are not light-dismissible by default, so there is a precedent. Surely it is a fair ask to be able to recreate the behaviour of .show() but using the top layer?

@mayank99
Copy link

mayank99 commented Mar 7, 2025

I completely agree that we need closedby for non-modal dialogs/popovers. This was part of the feedback I shared in #9373 (comment).

One use-case: I've worked on some very complex interfaces, where multiple non-modal dialogs may be open at the same time. These dialogs stay in top layer, can be dragged around, and allow moving focus between each other. It would be nice to have a declarative way of closing these dialogs using Esc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: dialog The <dialog> element topic: popover The popover attribute and friends
Development

No branches or pull requests

4 participants