What's new with dialog
Open and close dialogs without JavaScript
The command
and commandfor
attributes are currently supported in Chrome Canary.
command
and commandfor
are two new attributes that can be used on a HTML button
element.
Setting the command
attribute to "show-modal"
will open a dialog
elements. Setting it to "close"
will close a dialog
. The commandfor
attribute is used to specify which dialog
you want to open or close, by referencing an id
on the dialog
element.
<button commandfor="dialog-1" command="show-modal">Show modal</button>
<dialog id="dialog-1">
I am some dialog content...
<button commandfor="dialog-1" command="close">Close dialog</button>
</dialog>
closedby
attribute
The closedby
attribute was recently added to the HTML specification and is currently supported in Chrome Canary.
Modals are used in different ways. Some may ask an important question like “confirm deletion” that the user needs to answer before closing the dialog. Others, such as promotional marketing dialogs, should be easy to close without the user needing to hunt for a small close button.
Its common to let the user close a dialog by clicking outside of it, anywhere else on the page. This behaviour is known as light dismiss and can be enabled by setting the closedby
attribute to "any"
.
<dialog closedby="any">
I am some dialog content...
</dialog>
By default, a HTML <dialog>
is closed by the escape key. closedby="none"
disables this behaviour.
<dialog closedby="none">
Important question
<button>Delete everything</button>
<button>Save changes</button>
</dialog>
Toggle events
The dialog
element dispatches a beforetoggle
event just before it is shown or hidden.
dialog.addEventListener('beforetoggle', function(event) {
console.log(`${event.oldState}, ${event.newState}`);
});
The dialog
element dispatches a toggle
event immediately after it is shown or hidden.
dialog.addEventListener('toggle', function(event) {
console.log(`${event.oldState}, ${event.newState}`);
});
These events will fire regardless of how the dialog
was opened or closed: whether that be by pressing the escape key, light dismiss, pressing a button with a command
attribute set to "show-modal"
or "close"
, or via a JavaScript showModal()
, show()
or close()
method.
Further information about toggle
and beforetoggle
is available on MDN.
The toggle
and beforetoggle
events are currently supported in Firefox and Google Chrome/Microsoft Edge.
scrollbar-gutter
Its a common practice to set overflow: hidden
on the body
element when a dialog is open, to prevent the page from scrolling. When the scrollbar gets hidden, the space it took up is vacated, leading to a layout shift*. This is a jarring experience for users. The scrollbar-gutter
CSS property can prevent the layout from changing when a scrollbar is added or removed.
html {
scrollbar-gutter: stable;
}
scrollbar-gutter: stable
will reserve space for the scrollbar.
See the Pen dialog... by Ollie Williams (@cssgrid) on CodePen.
*Whether a scrollbar causes the layout to shift will depend on the type of scrollbar the user has chosen in their OS settings. On iOS and macOS, users can opt to use an “overlay scrollbar” which is placed above the content of the page and only shown when the user scrolls. Overlay scrollbars do not cause layout shifts. scrollbar-gutter
has no effect when a device is set to use overlay scrollbars.
Dialogs aren’t the only use case for scrollbar-gutter
. If content is dynamically added to a page, the page may go from having no scrollbar to having a scrollbar, so this property would again come in handy.
scrollbar-gutter
is supported in all browsers.