Let's explore the features of
Core aspects of usage
The HTML
Popups are frequently used to display simple notifications, such as cookie messages, disappearing toast alerts, tooltips, or right-click context menu elements.
Modal windows help users focus on specific tasks, such as notifications and warnings requiring user confirmation, complex interactive forms, and lightboxes for images or videos.
Popups don't prevent interaction with the page, while modal windows overlay the document, dim the background, and block other actions. This behavior works without additional styles or scripts; the only difference is the method used to open the dialog.
Dialog window opening methods
— popup:
<dialog>
<pre class="brush:php;toolbar:false">const popUpElement = document.getElementById("pop-up");
popUpElement.show();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
— modal window:
<dialog>
<pre class="brush:php;toolbar:false">const modalElement = document.getElementById("modal");
modalElement.showModal();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
In both cases, opening the
<dialog open>Hi, I'm a popup!</dialog>
Copy after login
Copy after login
Copy after login
Copy after login
Try it out:
- Opening a popup using the .show() method: https://codepen.io/alexgriss/pen/zYeMKJE
- Opening a modal window using the .showModal() method: https://codepen.io/alexgriss/pen/jOdQMeq
- Directly changing the open attribute: https://codepen.io/alexgriss/pen/wvNQzRB
Dialog window closing approaches
Dialog windows close the same way, no matter how they were opened. Here are a few ways to close a popup or modal window:
— with the .close() method:
<dialog>
<pre class="brush:php;toolbar:false">const popUpElement = document.getElementById("pop-up");
popUpElement.show();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
— by triggering the submit event in a form with the method="dialog" attribute:
<dialog>
<pre class="brush:php;toolbar:false">const modalElement = document.getElementById("modal");
modalElement.showModal();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
— by pressing the Esc key:
Closing with Esc works for modal windows only. It first triggers the cancel event, then close, making it easy to warn users about unsaved changes in forms.
Try it out:
- Closing a dialog box with the close method: https://codepen.io/alexgriss/pen/GRzwjaV
- Closing a dialog box through the submit form: https://codepen.io/alexgriss/pen/jOdQVNV
- Closing a modal window with the Esc key: https://codepen.io/alexgriss/pen/KKJrNKW
- Preventing a modal window from closing with Esc: https://codepen.io/alexgriss/pen/mdvQObN
Return value on close
When closing a dialog with a form using the method="dialog" attribute, you can capture the value of the submit button. This is useful if you want to trigger different actions based on the button clicked. The value is stored in the returnValue property.
Try it out: https://codepen.io/alexgriss/pen/ZEwmBKx
A closer look at how it works
Let's dive deeper into the mechanics of the dialog window and the details of its browser implementation.
The mechanics of a popup
Opening a
The mechanics of a modal window
A modal window is designed and works in a more complex way than a popup.
Document overlaying
When opening a modal window with .showModal(), the
The concept of layers refers to the stacking context, which defines how elements are positioned along the Z-axis relative to the user. Setting a z-index value in CSS creates a stacking context for an element, where the position of its children is calculated within that context. Modal windows are always at the top of this hierarchy, so no z-index is needed.
Learn more about the stacking context on MDN.
To learn more about the elements rendered in the top layer, visit MDN.
Document blocking
When a modal element is rendered in the top layer, a ::backdrop pseudo-element is created with the same size as the visible document area. This backdrop prevents interaction with the rest of the page, even if pointer-events: none CSS rule is set.
The inert attribute is automatically set for all elements except the modal window, blocking user actions. It disables click and focus events and makes the elements inaccessible to screen readers and other assistive technologies.
Learn more about the inert attribute on MDN.
Focus behavior
When the modal opens, the first focusable element inside it automatically gets focus. To change the initially focused element, you can use the autofocus or tabindex attributes. Setting tabindex for the dialog element itself isn't possible, as it's the only element on the page where inert logic doesn't apply.
After the dialog is closed, the focus returns to the element that opened it.
Solving UX problems with modal windows
Unfortunately, the native implementation of the
Scroll blocking
Even though the native HTML5 modal window creates a ::backdrop pseudo-element that blocks interaction with the content underneath it, the page scroll is still active. This can be distracting for users, so it's recommended to cut off the content of the body when the modal opens:
<dialog>
<pre class="brush:php;toolbar:false">const popUpElement = document.getElementById("pop-up");
popUpElement.show();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Such a CSS rule will have to be dynamically added and removed each time the modal window is opened and closed. This can be achieved by manipulating a class containing this CSS rule:
<dialog>
<pre class="brush:php;toolbar:false">const modalElement = document.getElementById("modal");
modalElement.showModal();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
You can also use the :has selector if its support status meets the project's requirements.
<dialog open>Hi, I'm a popup!</dialog>
Copy after login
Copy after login
Copy after login
Copy after login
Try it out: https://codepen.io/alexgriss/pen/XWOyVKj
Closing the dialog by clicking outside the window
This is a standard UX scenario for a modal window and it can be implemented in several ways. Here are two ways to solve this problem:
A method based on the behavior of the ::backdrop pseudo-element
Clicking on the ::backdrop pseudo-element is considered a click on the dialog element itself. Therefore, if you wrap the entire content of the modal window in an additional
and then cover the dialog element itself, you can determine where the click was directed — on the backdrop or on the modal window content.
Don't forget to reset the browser's default padding and border styles for the
<dialog>
<pre class="brush:php;toolbar:false">const popUpElement = document.getElementById("pop-up");
popUpElement.show();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Now, we apply the common styles for the modal window's borders and margins only to the inner wrapper.
We need to write a function that will close the modal window only when clicking on the backdrop, not on the inner wrapper element:
<dialog>
<pre class="brush:php;toolbar:false">const modalElement = document.getElementById("modal");
modalElement.showModal();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
Try it out: https://codepen.io/alexgriss/pen/mdvQXpJ
A method based on determining the size of the dialog window
This method is different from the first one, which needed an extra wrapper for the modal content. Here, you don't need any extra wrapping. All that's required is to check if the cursor's position goes outside the element's area when clicked:
<dialog open>Hi, I'm a popup!</dialog>
Copy after login
Copy after login
Copy after login
Copy after login
Try it out: https://codepen.io/alexgriss/pen/NWoePVP
Styling the dialog window
The
Styling the backdrop using the ::backdrop selector: https://codepen.io/alexgriss/pen/ExrOQEO
Animated dialog window opening and closing: https://codepen.io/alexgriss/pen/QWYJQJO
Modal window as a sidebar: https://codepen.io/alexgriss/pen/GRzwxgr
Accessibility
For a long time, the
When a
By default, the
Here are some ways to improve the accessibility of the
aria-labelledby
Always include a title inside dialog windows and specify the aria-labelledby attribute for the
<dialog>
<pre class="brush:php;toolbar:false">const popUpElement = document.getElementById("pop-up");
popUpElement.show();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
If you need to style the ::backdrop pseudo-element, ensure you also apply those styles to the corresponding .backdrop element to ensure compatibility with older browsers:
<dialog>
<pre class="brush:php;toolbar:false">const modalElement = document.getElementById("modal");
modalElement.showModal();
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
It's recommended to connect the polyfill via a dynamic import and only for browsers that don't support the
<dialog open>Hi, I'm a popup!</dialog>
Copy after login
Copy after login
Copy after login
Copy after login
Conclusion
The native HTML5
In this article, we discussed the following topics:
- Problems the
- Interaction with the
- How dialog windows work at the browser level;
- Common issues with modals and their solutions;
- Improving accessibility of the
- Expanding browser support for the
Finally, I invite you to check out the modal window component implementation in pure JS, which takes into account the main aspects discussed in the article: https://codepen.io/alexgriss/pen/abXPOPP
That's all I wanted to share about working with the
The above is the detailed content of How to Use the HTMLlt;dialog> Element. For more information, please follow other related articles on the PHP Chinese website!