Enhance Dialogs with the closedby Attribute
The native <dialog> HTML element is a thing of beauty. It enables you to easily
create accessible, modal dialogs that work well for all users. And it has been
supported by all modern browsers since 2022.
But it gets even better: The new closedby attribute allows you to define which user
actions will close the dialog. You can add light dismiss behavior, or go the other way: e.g., prevent
the ESC key from closing the dialog.
Photo: © Miguel Á. Padriñán / pexels.com
We’ll take a look at the technical specification and some use cases for the new attribute.
How it works
The HTML specification
defines closedby as an enumerated attribute with the following keywords:
any– Close requests or clicks outside close the dialog.closerequest– Close requests close the dialog.none– No user actions automatically close the dialog.
If you don’t set the closedby attribute on a modal dialog, then it behaves as if the
value was closerequest . This means, pressing the ESC key on
desktop platforms, or a “back” or “dismiss” gesture on mobile platforms, will close the dialog.
Use Cases
Light Dismiss for Informational Dialogs
Some dialogs only present information. The user isn’t expected to make a decision or fill in a form. In my opinion, this is a perfect use case for adding light dismiss behavior: The dialog should close when the user clicks or taps outside it.
Before we had the closedby attribute, you needed additional JavaScript code to implement
light dismiss. See my article “Why you should use the Native Dialog Element” for
an example. Lucky for us, now we only need the following HTML code:
<dialog closedby="any">
<!-- content -->
</dialog>
Awesome! 🥳
Prevent Accidental Closing
Dialogs are a great way to encapsulate workflows like, e.g., the data entry via a form. You can also handle the onboarding process for your web application with a dialog.
In all these cases, you’ll want to prevent the user from accidentally closing the dialog, e.g., via
the ESC key. They would lose the data they had already filled in the form, or not be
able to access the onboarding dialog again.
Therefore, you should set closedby=“none” on the dialog. Now the user can only close
the dialog via a developer-specified mechanism, like a close button. Here’s an example:
<dialog id="mydialog" closedby="none">
<!-- content -->
<button commandfor="mydialog" command="close">
Continue
</button>
</dialog>
Maybe you’re wondering about the command and commandfor
attributes on the close button. They’re part of a new web feature called
Invoker Commands API. You don’t have
to use them in your dialogs. But I like their simplicity and elegance, so I wanted to include them in my
code example. 😉
Browser Support
The closedby attribute is already supported by Firefox, Chrome and Edge.
Thanks to Interop 2026, Safari/WebKit should catch up until the end of the year.
Useful Resources
- The closedby attribute (MDN)
- “Accessibility Engineering — Let the Web Platform do the Work” (section: “The dialog element: Always on top”)
- “Native Dialogs and the Popover API — What you need to know”
Posted on