Amit Merchant Software developer, writer, artist, and noob gardener.

Why you should be using the dialog element

4 min read 1159

Why You Should Be Using The Dialog Element

Dialogs are an integral part of any user interface, be it the web, mobile, or any other that exists today.

Do you want to confirm something from the user? You present the user a dialog with selectable options. Do you want to gather info from the user? You use a dialog with a submittable form input. There are numerous use cases when it comes to using the dialog in your UIs.

You can use dialogs by installing JavaScript libraries in your project, and these are available in any kind of framework you’re using. For instance, if your project is in React, you can use the react-aria-modal. For Angular, you can use ngx-smart-modal. Or if you’re working with good old jQuery, you can use jquery-modal.

Third-party libraries are great, but they do come with an additional overhead to your project that not only adds a certain amount of complexity but also increases the overall bundle size of your app.

On top of this, you’re going to install the entire library with all the bells and whistles even if you’re only going to use certain features of that library. This is not great in my opinion.

That’s where the browser’s native <dialog> element comes into play. It’s everything you’ll ever want in a dialog, and now that Safari has added the support for the <dialog> element starting v15.4, there isn’t any excuse not to use them in production!

What is a <dialog> element?

<dialog> is an HTML element that represents a dialog box such as alert, confirmation, inspector, or subwindow.

A very basic <dialog> element would look like so:

<dialog>
  Hey, this is an HTML dialog!
</dialog>

Since the <dialog> wouldn’t be visible by default, we would need to pass in an open property to make it visible:

<dialog open>
  Hey, this is an HTML dialog!
</dialog>

Here’s how it would look:



See the Pen
The basic <dialog>
by Amit Merchant (@amit_merchant)
on CodePen.

Customizing <dialog>’s appearance

You might be wondering, where does that black border in the example come from? The answer is every user agent (browser) would apply a default style to the <dialog> element that would look something like this:

Default Dialog CSS

The dialog’s design can be easily customized. For instance, if you want to remove the default border and add a drop shadow instead and a few more niceties, here’s how you can do it:

dialog {
  border: none;
  box-shadow: #00000029 2px 2px 5px 2px;
  border-radius: 10px;
  padding: 30px;
  background-color: pink;
  font-family: sans-serif;
  font-size: 20px;
  font-weight: bold;
}

And here’s how the customized dialog would look:

See the Pen
Customising <dialog>
by Amit Merchant (@amit_merchant)
on CodePen.

Adding interactivity

In real-world scenarios, you wouldn’t be using dialog boxes straight-up like this. You may want to trigger the dialog on some action. Let’s say when clicking a button.

Check out this example:

<dialog id="demoDialog">
  Hey there! This is a dialog
  <button id="closeDialog">Close dialog</button>
</dialog>
<menu>
  <button id="openDialogButton">Open dialog box</button>
</menu>

As you can tell, we have a dialog with an ID demoDialog. Now, if we want to open this dialog by clicking the Open dialog box button, here’s how we can do it:

var openDialogButton = document.getElementById('openDialogButton');
var demoDialog = document.getElementById('demoDialog');
var closeDialog = document.getElementById('closeDialog');
// "Open dialog box" button opens the <dialog> 
openDialogButton.addEventListener('click', function () {
  if (typeof demoDialog.showModal === "function") {
    demoDialog.showModal();
  } else {
    console.log("The <dialog> API is not supported by this browser");
  }
});
closeDialog.addEventListener('click', function() {
  demoDialog.close();
})

To open the dialog, we can programmatically call the showModal() method on the <dialog> instance through JavaScript. But before that, it would be nice to first check whether the browser supports the <dialog> or not by checking if showModal exists in the dialog’s object.

We can call the close() method on Close dialog to close the <dialog>.

N.B., you can close the <dialog> using the Esc key as well.

Here’s everything in action:

See the Pen
Opening a <dialog> programatically
by Amit Merchant (@amit_merchant)
on CodePen.

Handling user’s input

If you want to handle user-entered input from within the <dialog>, you can define a <form> inside it and set its method as "dialog".

<dialog id="collectEmail">
  <form method="dialog">
    <p>
      <label>
        Email:
        <input type="email" name="email" id="email" placeholder="Enter your email">
      </label>
    </p>
    <menu>
      <button value="cancel">Cancel</button>
      <button id="confirmBtn" value="default">Confirm</button>
    </menu>
  </form>
</dialog>
<menu>
  <button id="openEmailDialog">Submit user's email</button>
</menu>
<output aria-live="polite"></output>

When the form is submitted, the dialog will close automatically, and then, you can handle the input value on the dialog’s close event like so:

collectEmail.addEventListener('close', function() {
  let email = document.getElementById('email').value;
  outputBox.innerHTML = `User's email: <b>${email}</b>`;
});

Putting it all together:

See the Pen
<dialog> input demo
by Amit Merchant (@amit_merchant)
on CodePen.

Some more tweaks

Changing <dialog>’s backdrop

It’s also possible to change the dialog’s backdrop when it’s opened using the ::backdrop pseudo CSS property:

dialog::backdrop {
  background-color: #673ab752;
}

Here’s how this would look:

See the Pen
<dialog> backdrop
by Amit Merchant (@amit_merchant)
on CodePen.

Closing the <dialog> when clicking outside of it

By default, when the <dialog> is opened, it cannot be closed when clicking outside of the dialog’s area. If we want to introduce this behavior, we can get the dialog’s DOMRect using the getBoundingClientRect() on clicking the dialog.

We can then get the coordinates of the click and check if it falls outside of the dialog’s rectangle. And based on this, we can call the dialog’s close() event like so:

collectEmail.addEventListener("click", event => {
    const rect = collectEmail.getBoundingClientRect();
    if (event.clientY < rect.top || event.clientY > rect.bottom ||
        event.clientX < rect.left || event.clientX > rect.right) {
        favDialog.close();
    }
});

Here’s the behavior in action:

See the Pen
<dialog> demo
by Amit Merchant (@amit_merchant)
on CodePen.

Try clicking outside of the dialog!

In closing

And that’s about it for the native HTML <dialog> element that has been now widely supported throughout the major browsers including our beloved Safari!

So, this is a no-brainer if you’ve got use cases where you need to use dialogs and you end up using the <dialog> element. Happy coding!

: Full visibility into your web and mobile apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.

.
Amit Merchant Software developer, writer, artist, and noob gardener.

2 Replies to “Why you should be using the dialog element”

    1. Hey Karol,

      By using it in the production I meant the dialog element is supported by all the modern browsers except a few obscure browsers, such as IE, Opera Mini, KaiOS browser, UC browser etc, that still doesn’t support the dialog element.

      The market share of these browsers is fairly low at this point. And that’s why I said it’s safe to use it in the production.

Leave a Reply