Introduction
HTML 5.2 brought us the dialog
element! 🙌
For now, only Chrome implemented it, but other browser vendors will certainly follow if they want to be fully HTML-compliant. (In Firefox, it is already behind a flag.) There's also a polyfill for it.
Let's now examine this relatively new and shiny HTML element. 🔬
Demo
In the codepen below, I created a fully functional modal without writing a single line of CSS. 🤓
So, how does all this work?
Well, it is actually quite simple. We just need to use the dialog
element and add the open
attribute to display it (by default it is hidden). We can toggle that attribute on by using the showModal
method provided on the HTMLDialogElement. We call the close
method to toggle it off.
const modal = document.querySelector('#modal')
modal.showModal() // opens the modal
modal.close() // closes the modal
You can notice a few neat things that the dialog
element does automatically for us:
- The dialog is centered in the middle of the screen.
- The background is dimmed and elements behind the modal can't be interacted with.
- The dialog has already basic styling (quite ugly, but more on this later).
- The
escape
key closes the modal.
And by adding method="dialog"
to the form tag:
- The first interactive element (in the DOM order) is focused.
- Upon form submission, the dialog is close and the value of the element that triggered the submit event is saved on the
returnValue
property of the HTMLDialogElement.
In our codepen above, both buttons trigger the closing of the modal. When the modal is closed, it emits a close
event. In our demo, modal.returnValue will contain either 'yes' or 'no' (or an empty string if the user presses [escape]).
modal.addEventListener('close', () => {
console.log(modal.returnValue) // In our case: 'yes', 'no' or ''
})
Customization
The dialog element comes with a default user agent stylesheet, but can be fully customized. You can even change the modal backdrop in this way:
#modal::backdrop {
background-color: rgba(0, 0, 0, 0.4)
}
An example of customization using Tailwind CSS
Resources
In this post, I only cover some aspects of the dialog element. For detailed information about this topic, I recommend the following links:
https://alligator.io/html/dialog-element/
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
https://demo.agektmr.com/dialog/
Top comments (9)
Nice post! There's also a polyfill: github.com/GoogleChrome/dialog-pol... (shameless self-promotion)
And Firefox has an incomplete implementation behind a flag: bugzilla.mozilla.org/show_bug.cgi?...
Thank you for your comment!😃
I've updated my post to mention your polyfill. But I feel like the biggest “selling point” for using the dialog element is its ease of use. Personally, if I have to install a npm package and then register DOM elements, I would rather create my own modal with CSS or install a npm package like vue/react-modal if I am using a framework.
Sure, but
dialog
is only supported in Chrome, so in my opinion it's unreasonable to ship it without a polyfill.I appreciate your argument, but I think it implies that you should always just create your own modal and not use the built-in one :)
Yes, in the current state of adoption, your polyfill is the only way to use the
dialog
element in production.And if a developer uses React or Vue, he/she can easily overcome the polyfill's major limitation (stacking context) by using portals. ✌️
Cool Post!
While I do like the Idea of having a
native
Dialog element, It doesn't always turns to be that good, think of theselect
element for example, it is always a mess to style one in a good way across browsers, that you end up using a third party library that renders a consistentselect
element, even the MDN Docs say so:I think this is one of the reasons the
dialog
element hasn't been rushed to implement.That being said, it is nice to know it could be an alternative in the future.
Thanks for your comment 😃
I think that the issue of styling has been taken into consideration in the design of the dialog element. It is very easy to override the default styles and it even provides a pseudo-element (::backdrop) for customizing the background.
So in the end, it is as easy as styling a div tag, but with the added accessibility benefit.
Very nice post!
I actually don't get it on what the W3C is up to. Years of using propietary MS IE window.showModalDialog, then going into some HTML standars that ended draw back, and now this, a (brand new) implementation for the same purpose.
I remember when browsers stopped the modal functionality because implementations where so bad. What will be the difference now?
I suppose someone figured out how to make this modals modal to their own window parent, so now, there is no problem in having a modal dialog inside your page, if you want to switch to another tab to see another page, now you just can.
I hope this to be a relief for all of us developers, who need some sort of synchronism in our apps, without being forced to rely on 3rd party libraries or no standard behaviours.
Thanks a lot for the post.
These are great news.
Thank you for reading my post 😊
Yes, I do think that the end goal is to set standards for better accessibility.
About this, Jen Simmons wrote:
Thank you so much for this. i was looking for a non css option to create a modal and this is exactly what i needed