With release of HTML 5.2 comes the dialog
element. The dialog element has been around for a while now but was an experimental technology.
Previously, if we wanted to build a modal or a dialog box of any sort, we needed to arrange our markup in a way where we have a backdrop, a close button, keep events trapped within the dialog, find a way to pass message out of the dialog… It was really complicated. The dialog element solves all the problems above and more.
Heads up: I’m going to interchange between modal and dialog a lot.
Quick comparison between bootstrap modal and the new dialog element
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The markup above is for bootstrap, compare that to this
<!-- Trigger the modal with a button -->
<button type="button" class="btn">Open Modal</button>
<!-- Modal -->
<dialog open>
Native dialog box!
</dialog>
Getting started
We’ve seen the simplest markup for a dialog element, there are some basic operations you’ll need to understand to get it to work.
You may have noticed the open
attribute on the dialog above. Adding that attribute to the element will force the dialog to show, removing it will do otherwise. The dialog will also be absolutely positioned on the page.
Default dialog styling
The dialog element exposes some methods that we can use to manipulate its behavior.
const modal = document.querySelector('dialog')
const openBtn = document.querySelector('.open-modal')
const closeBtn = document.querySelector('.close-modal')
// showModal() makes modal visible (adds `open` attribute)
openBtn.addEventListener('click', () => modal.showModal())
// close() hides modal (removes `open` attribute)
closeBtn.addEventListener('click', () => modal.close())
As you can see from the pen above, the dialog element exposes the showModal()
and close()
methods. We use these methods to show and hide the modal respectively.
Sending data out of the modal
We can use modal.returnValue
to send data out of the modal. This way, we have native control over what we transmit out of the modal.
First, let’s send data out of the dialog. We do that by passing the data we want to send through the close()
method.
// close() hides modal (removes `open` attribute and send data out the modal)
closeBtn.addEventListener('click', () => modal.close('Lorem ipsum'))
We can capture the data sent out of the modal by calling the modal.returnValue
closeBtn.addEventListener('click', () => {
modal.close('lorem')
alert(`modal says: ${modal.returnValue}`)
})
Styling the modal
We would style a dialog
just as we would any CSS element… almost any CSS element ?. The dialog
component also brings in a new ::backdrop
pseudo selector that we can use to style the backdrop
dialog {
padding: 3rem;
border-radius: 4px;
border: none;
box-shadow: 0 4px 6px lightgray;
transition: transform .5s;
transform: scale(.1);
&[open] {
transform: scale(1);
}
}
::backdrop {
background: rgba(black, .5);
}
In Conclusion
The dialog component is not yet supported by every browser there is. All current variations of Chrome (desktop or mobile) does, but other browsers are lacking.
To remedy this, we need to polyfill the dialog. Fortunately for us, the team behind Chrome has built one for us. It’s called dialog polyfill.
Source: Scotch