All the major browsers now support the <dialog >
element. Why add this HTML element? User land code, code that developers write to fill in gaps of the browser, was doing similar things repeatedly, especially around focus trapping, and browser engines responded by adding this functionality directly in the browser.
Focus Trapping
What is focus trapping? It's a feature where you do not want focus outside a specific element, and that element typically contains focusable elements.
For example, a form in a modal to confirm an action: As a user uses the keyboard to navigate, they go to the next focusable element, e.g. a button.
If they reach the last focusable element in the modal, without focus trapping, the focus would go to the next focusable element in the document object model (DOM). With focus trapping, you go from the last focusable back to the first focusable element in the parent element.
In user land, popular packages like focus-trap have enabled developers to incorporate focus trapping.
<dialog> for Modal Dialogs
With the dialog element, you get this for free, although there is a gotcha. If you add a dialog element to the page with the open attribute set, the dialog element will become visible on the page; however, focus trapping will not work as you'd expect in a modal.
From the API documentation:
Note: While you can toggle between the open and closed states of non-modal dialog boxes by toggling the presence of the open attribute, this approach is not recommended.
To get focus trapping working, the JavaScript API is required. You can display a modal on the screen by calling the HTMLDialogElement showModal method.
Note that you'll need to view this CodePen in full view because, for some reason, modal dialog focus trapping does not work in the CodePen editor view.
Not only do you get focus trapping, you also get modal close functionality that people have come to expect via the Escape key.
All of that is already amazing, but another common thing people were doing in user land was adding a background to block out users from interacting with the page. With the <dialog>
element, we can add a ::backdrop
pseudo-element that does this for you. All you need to do is style it. In the CodePen above, uncomment out this code in the CSS panel to see this in action.
dialog::backdrop {
background-color: purple;
opacity: 0.55;
filter: blur(100px);
}
<dialog> for Non-Modal Dialogs
The structure of a non-modal dialog element is the same as a modal dialog. The main difference is to show a non-modal dialog, you need to call the HTMLDialogElement show method.
With a non-modal dialog, the user is not blocked from navigating the rest of the page, i.e. no focus trapping, and the Escape key will not automatically close the dialog.
Closing a dialog
To close a dialog or modal, we can use the HTMLDialogElement close method.
const modal = document.querySelector("dialog");
// some button in the dialog that has a click event listener registered
modal.querySelector("button").addEventListener("click", () => {
modal.close();
});
Wrapping up
The web platform keeps getting better. It's great to see pain points in user land that had user solutions come natively to browser land.
References
- Using JavaScript to trap focus in an element
- MDN - <dialog>: The Dialog element
- GitHub issue element should trap focus from the w3c/html repository.
- Dialog - web.dev
Stay saucy peeps!
If you would like to know more about my work in open source, follow me on OpenSauced.
Top comments (21)
Indeed a good addition to the HTML standard, and a nice article. I would also cover on the "closing the dialog" section on the option to close on click outside, which is a common UX behavior. Your cover image made me laugh... I had never had 13 people cheering me when adding a modal to my UI... 😆
Glad you enjoyed the article! I always have generwting cover images now. 😆
oh wow this is cool
Thanks Medea!
we've gone such a long way since bootstrap's 40 lines of code modals 🤣
It is in tailwind now
Thanks for the post; it really sums up the issue from the past and shows how the dialog element is helpful now!
Great post.
Thanks Lymah!
Thanks!
Cool
Good info!
Thanks Scott!
Nice post Nick, but how can pass the value of the input element in you dialog back to the page?
I think I figured it out: codepen.io/cdoremus/pen/MWxrpKm
That’s out of the scope of the blog post, but you can just bind an event to a button in the modal or to the form or if your using a framework, use their way of attaching events.
in your css add
dialog::backdrop {
background: rgba(0, 0, 0,.5);
backdrop-filter: blur(0.5rem);
}
Den you get a blurred slightly darkened background
That's correct. It's an example to show how to blur out the rest of the page aside from the modal which is the focus.