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 · 7 comments
Open

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

o-t-w opened this issue Mar 5, 2025 · 7 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 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).

<dialog popover="auto"> has equivalent close behaviour to closedby=any. <dialog popover="manual"> has the same close behaviour as closedby=none. There's no equivalent for closedby=close-request. For some non-modal dialog use cases, I do not want light dismiss when the user clicks the page but I do want the escape key to close the dialog. 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. Both the following examples should be specced to work:

<dialog closedby="closerequest" popover="manual">
A non-modal popover dialog in the top layer.
</dialog>

<dialog closedby="closerequest" popover="auto">
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:

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

Notification dialogs are another case where I would use closedby="closerequest".

Image Image

Let's take newsletter sign-up form as an example. Some users are desperate to sign up. Others see it as clutter on the page and spam, and want to dismiss it as quickly as possible. In that scenario, <dialog popover="auto"> feels too easy to dismiss. <dialog popover="manual"> is too hard to dismiss. closedby="closerequest" feels just right. If I land on the page and am not interested in the newsletter, I click the escape key and the dialog is instantly gone: that's good UX. If I actually want to sign up and accidentally close the dialog via light-dismiss, that's bad UX.

Non-modal dialogs that use the .show() method are not light-dismissible by default, so there is a precedent.

@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.

@o-t-w
Copy link
Author

o-t-w commented Mar 13, 2025

From a user's point of view, I think there's something of an expectation that a <dialog popover> is light dismissible.

Some aspects of dialog behaviour override usual popover behaviour. Showing a dialog via the popover API uses the focus behaviour of dialog: it focuses the first focusable element within the dialog. This is different from how focus usually works for a popover. So there is a precedent of the dialog element altering typical popover behaviours. I think there's a developer expectation that light dismiss would be the default behaviour of any element with popover="auto", but that dialog-related attributes should still work.

@scottaohara
Copy link
Collaborator

scottaohara commented Mar 14, 2025

i think a challenge here is that while there are some custom implementations of non-modal dialogs which allow them to be closed by escape key, that behavior is (correctly, imo) often limited to when keyboard focus is within the non-modal dialog.

right now, if closedby is used on a non-modal dialog, esc key can be used anywhere in the web page to dismiss the dialog. I'd submit that's not the behavior this request is looking for.

The use case of wanting a non-modal dialog in the top layer so that one can interact with it and content of the primary web page means that someone is likely to interact with content in the primary interface which requires the user press the escape key - but in doing so, they wouldn't want the dialog they're referencing / which contains controls they're using to edit their interface to dismiss.

so, should non-modal dialogs / dialog popover=manual allow for escape key to dismiss them when focus is within said dialogs? sure i guess... i'm personally of mixed opinion on how necessary that is.

but i see a conflict of UX here with non-modal dialogs. esc key to dismiss outside of a popover (which may be a dialog) makes sense. esc key to dismiss outside of a non-modal dialog that is meant to be persistent - not a good idea, BUT esc key to dismiss when focus is within that non-modal dialog - that's a valid use case.

@o-t-w
Copy link
Author

o-t-w commented Mar 18, 2025

"right now, if closedby is used on a non-modal dialog, esc key can be used anywhere in the web page to dismiss the dialog. I'd submit that's not the behavior this request is looking for."

I don't entirely agree. If I land on a webpage and there's a dialog I'm not interested in, I'd like to close it immediately with the escape key, without needing to focus it. Yes potentially a user could press the escape key to close something else on the page (a popover menu etc) which would also close the dialog, which might be unintentional. If it's a newsletter sign-up dialog, for example, I think that's ok. But I do agree there may be other cases where it may not be desired behaviour. Gmail is an example where a user can close dropdown menus using the escape key, but that won't close the box where you compose a new message. If you focus on the new message dialog and press escape, it will close it.

Image

From a user's point of view

Realistically, the people making UX decisions are often "stakeholders". If the head of marketing's main agenda is getting people to sign up to an email, they are going to demand that is does not have light dismiss functionality, and a developer is going to need to implement that.

@scottaohara
Copy link
Collaborator

your example of the message dialog is in line with what i was saying though.

pressing escape key anywhere in the gmail interface doesn't immediately close that dialog - if other non-dialog popovers are open - those will be closed first - and then if repeatedly pressing esc after dismissing such popups, focus will be move to the compose dialog, and only then if the esc key is pressed again the dialog will be dismissed.

If that were the behavior specifically for non-modal dialogs, then that might be ok. But that's not the current behavior as I already explained. So, again if this feature were to be allowed for non-modal dialogs the current behavior is not really ideal even with your cited example.

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

5 participants