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>

I am some dialog content...

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>

I am some dialog content...

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>

Important question

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.