The dialog box is a common user interface design pattern that comes up over and over again on websites — so often that the W3C came up with some standardized HTML markup to describe a dialog window.
Traditional dialog windows created with other HTML markup and CSS have been implemented in most front-end frameworks for a long time, and that’s probably still the way to go since the HTML dialog element still has limited browser support.
But if front-end frameworks are still the better choice, why create a standardized dialog element?
Well, there are many reasons, but chief among them is accessibility by screen readers and enabling things like search engine crawlers and machine learning agents to interpret the dialog window. As browser support improves over time, this standard will be the clear choice to create modal windows moving forward.
First, we’ll focus on the HTML markup for the dialog element, then we’ll add some JavaScript later.
The folder structure might look like this:
project
| — index.html
| — app.js
| — main.css
Inside the index.html file, let’s create the dialog element with an opening and closing tag:
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
</head>
<body>
<dialog>
</dialog>
</body>
http://app.js
</html>
However, this won’t show anything on the page just yet. In order for this to appear, we need to add the boolean attribute open to the dialog element:
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
</head>
<body>
<dialog open>
</dialog>
</body>
http://app.js
</html>
Inside the dialog element, we’ll create a simple form with a text input of type text
and a button of type submit
:
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
</head>
<body>
<dialog open>
<form method="dialog">
<input type="text">
<button type="submit">SUBMIT</button>
</form>
</dialog>
</body>
http://app.js
</html>
Note: Here I’ve set a method of the form to dialog. This is a new form method that works in coordination with the parent dialog element. When the submit button is pressed, it will submit the form and dismiss the dialog window.
Now we’ll create some buttons that will allow us to make the dialog window reappear. These will need JavaScript to work, which we will add later.
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
</head>
<body>
<dialog open>
<form method="dialog">
<input type="text">
<button type="submit">OK</button>
</form>
</dialog>
<button id="openDialog">Dialog</button>
<button id="openModalDialog">Modal Dialog</button>
</body>
http://app.js
</html>
So, here we have created two buttons: one with the ID openDialog
, and another with the ID openModalDialog
. Once we add some JavaScript, the first button will open the dialog window just like we saw above. However, the second button will open a dialog window that blocks other page interactions.
This is a common design pattern because when a dialog window is open, you often need the user to perform some sort of interaction before they continue using the rest of the application.
For writing the JavaScript, I will remove the open attribute from the dialog element and then add an ID attribute so we can select it with our JavaScript, just like the buttons.
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
</head>
<body>
<dialog id="dialogWindow">
<form method="dialog">
<input type="text">
<button type="submit">OK</button>
</form>
</dialog>
<button id="openDialog">Open Dialog</button>
<button id="openModalDialog">Open Modal Dialog</button>
</body>
http://app.js
</html>
Inside the JavaScript (app.js) file, we will write our event-based code in an anonymous function, which will be executed on page load.
First, we will gather the elements on the page, along with the variables — the dialog window and the two buttons. We’ll create a variable for each and get them by their ID.
(function() {
let openDialog = document.getElementById('openDialog');
let openModalDialog = document.getElementById('openModalDialog');
let dialogWindow = document.getElementById('dialogWindow');
})();
Next, we will create two event listeners, one for each button.
We will add an EventListener
to the openDialog
button so that when it’s clicked, the function show()
will execute. The show()
function displays the dialog element on the page the same way it did when we used the open attribute earlier in our HTML.
(function() {
let openDialog = document.getElementById('openDialog');
let openModalDialog = document.getElementById('openModalDialog');
let dialogWindow = document.getElementById('dialogWindow');
openDialog.addEventListener('click', () => {
dialogWindow.show();
})
})();
Note: I have styled the buttons so that they are visible on the GIF above, but it won’t affect functionality in any way.
We’re going to do the same thing for our open modal window dialog as we did above: add an EventListener
to the openModalDialog
button so that when it’s clicked, the function showModal()
will execute.
So here, instead of the show()
function, we’re using the showModal()
function, which will still show the dialog window. But this time, the rest of the page will have a gray, transparent overlay that will block any other mouse clicks.
(function() {
let openDialog = document.getElementById('openDialog');
let openModalDialog = document.getElementById('openModalDialog');
let dialogWindow = document.getElementById('dialogWindow');
openDialog.addEventListener('click', () => {
dialogWindow.show();
})
openModalDialog.addEventListener('click', () => {
dialogWindow.showModal();
})
})();
A polyfill is a piece of code that implements a feature that isn’t natively supported by particular web browsers. Typically, they first check whether a browser supports an API and use that if available; otherwise, they implement their logic to make it work on the browser.
Right now, only Chrome and Opera fully support the HTML dialog element, and in order to use it in Firefox, the user must explicitly enable the feature.
But we can still use the HTML dialog element in other browsers(Safari, IE, etc.) using dialog-polyfill, which is maintained by Google Chrome. The polyfill will add support for non-supporting browsers; it also supports IE9 and above.
A couple things to note: adding polyfill in our JavaScript (app.js) file won’t affect the HTML dialog element working on Chrome and Opera in any way. There will only be the single app.js file.
Additionally, if we want to use the HTML dialog element only on Chrome or Opera, we won’t need a polyfill. But if we want to use it on all browsers — which would probably be the case — we will have to use polyfill until there is complete support on the rest of the browsers.
The updated folder structure might look like this:
project
| — index.html
| — app.js
| — main.css
| — dialog-polyfill.css
| — dialog-polyfill.js
dialog-polyfill.css
in the head of your document.
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
<link rel="stylesheet" href="dialog-polyfill.css">
<link rel="stylesheet" href="main.css">
</head>
<body>
<dialog id="dialogWindow">
<form method="dialog">
<input type="text">
<button type="submit">OK</button>
</form>
</dialog>
<button id="openDialog" class="button">Open Dialog</button>
<button id="openModalDialog" class="button">Open Modal Dialog</button>
</body>
http://app.js
</html>
2. Include the JavaScript dialog-polyfill.js
anywhere before referencing dialogPolyfill
.
<!doctype html>
<html>
<head>
<title>HTML Dialog Element</title>
<link rel="stylesheet" href="dialog-polyfill.css">
<link rel="stylesheet" href="main.css">
</head>
<body>
<dialog id="dialogWindow">
<form method="dialog">
<input type="text">
<button type="submit">OK</button>
</form>
</dialog>
<button id="openDialog" class="button">Open Dialog</button>
<button id="openModalDialog" class="button">Open Modal Dialog</button>
</body>
http://dialog-polyfill.js
http://app.js
</html>
3. Create the <dialog>
element within the HTML document (we have already created one above).
dialogPolyfill.registerDialog()
function, passing it one node at a time.(function() {
let openDialog = document.getElementById('openDialog');
let openModalDialog = document.getElementById('openModalDialog');
let dialogWindow = document.getElementById('dialogWindow');
dialogPolyfill.registerDialog(dialogWindow);
openDialog.addEventListener('click', () => {
dialogWindow.show();
})
openModalDialog.addEventListener('click', () => {
dialogWindow.showModal();
})
})();
5. Use your <dialog>
element.
Now we have covered the essentials of the dialog element in HTML. If you’re interested in learning more, consider reading these resources from Mozilla and Can I use…, as well as the official spec.
I hope you’ve found this post informative and helpful. I would love to hear your feedback!
Thank you for reading!
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowImplement graceful degradation in frontend apps by handling failures, mitigating API timeouts, and ensuring a seamless UX with fallbacks.
Use htmx and Go to build high-performance websites, leveraging server-side rendering and minimal JavaScript for fast and efficient applications.
The scroll-select box is a great tool for frontend developers to improve the user experience of their applications. Learn how to build a scrollable date picker that mimics the iOS style, but with the exemption of the <select>
element.
For those just getting started with deploying their first application, Deno Deploy’s simplicity might be exactly what you need; no complex configuration files to wrestle with or cloud concepts to master before getting your app live.