How to create an HTML5 dialog and modal?

html5 dialog modal

In this post we will go through a simple process of creating a pure HTML5 modal, using dialog elements. There is no need to use any frontend libraries or frameworks anymore, we can accomplish this with pure HTML, vanilla JS, and CSS. Let’s dive right in!

Introduction

HTML5 dialog element was introduced back in 2014 but not all browsers were supporting it until now. We can use it anywhere now. It is and it behaves like a normal HTML element, it has open and closed tags like this <dialog></dialog>.

We can create modal with the HTML now ! 🥳

There is a small difference between a modal and a dialog, that we need to discuss. Modal is an element that should cover the entire screen and take all the user’s attention while the dialog is just a popup that serves some information to the user and you can actually use the page while the dialog is open. When the modal is open you can’t do anything except scroll through the page.

Dialog

Shows like inline popup
Users can use the page while it’s open
Doesn’t take up the entire screen

Modal

Takes up the entire screen, usually centered in the middle
Has the backdrop functionality
Users can’t do anything until they close it, explicitly

Preview HTML5 Modal

Checkout the preview of the modal that you will be building

Choose your favorite hero!

Creating an HTML5 dialog

To create a simple dialog we can use the following HTML code

<button id="dialogButton">Open a dialog</button>

<dialog id="simple-dialog">
  This is a dialog
  <button id="dialogClose">Close</button>
</dialog>

As you can see we have a button to open the dialog. The dialog itself, and in addition to all that we have a close button to close the dialog. When open it will give us the dialog as shown in the image below.

Simple example of the html dialog
A simple example of the HTML dialog

Now to show the dialog and to close it we are going to write some JS code. What we need is really simple. Two click listeners for two buttons, one for opening and one for closing the dialog.

// Get the dialog element
const simpleDialog = document.querySelector('#simple-dialog');

// Add the click listener for open dialog button
document.querySelector('#dialogButton').addEventListener('click', () => {
// Show the dialog by simply calling show() method on it
  simpleDialog.show();
});

// Add the click listener for close dialog button
document.querySelector('#dialogClose').addEventListener('click', () => {
// Close the dialog by simply calling close() method on it
  simpleDialog.close();
});

That’s all there is to it, guys! If the code above is not familiar please check out my other posts. Like this one!

Hey guys, now I know how to create the dialog without bootstrap, jquery or anything else! 😆😎🤓

Creating an HTML5 modal

For modals we would do the exact same thing, just instead of calling the show() method we are going to call a showModal() method. Let’s create the modal with the form inside, something that you would usually do for a client.

The html part will be more or less the same:

<!-- A modal dialog containing a form -->
<dialog id="favDialog">
  <div class="title-row">
    <h1>Choose your favorite hero! </h1>
  </div>
  <form>
      <label>
        Favorite hero:
        <select>
          <option value="default">Choose…</option>
          <option>Iron man</option>
          <option>Black widow</option>
          <option>Spider man</option>
          <option>Bat man</option>
        </select>
      </label>
    <div id="buttons-row">
      <button id="cancelBtn" value="cancel" formmethod="dialog">Cancel</button>
      <button id="confirmBtn" value="default">Confirm</button>
    </div>
  </form>
</dialog>
<p>
  <button id="showModal">Open a modal</button>
</p>
<output></output>

Now the JS will be a bit more complicated since we do want to show the selected option.

const showButton = document.querySelector('#showModal');
const favDialog = document.querySelector('#favDialog');
const outputBox = document.querySelector('output');
const selectEl = favDialog.querySelector('select');
const confirmBtn = favDialog.querySelector('#confirmBtn');

showButton.addEventListener('click', () => {
  favDialog.showModal();
});

selectEl.addEventListener('change', (e) => {
  confirmBtn.value = selectEl.value;
});

favDialog.addEventListener('close', (e) => {
  outputBox.value = favDialog.returnValue === 'default' ? 'No return value.' : `ReturnValue: ${favDialog.returnValue}.`;
});

confirmBtn.addEventListener('click', (event) => {
  event.preventDefault();
  favDialog.close(selectEl.value);
});

HTML5 Modal Code Break Down

Firstly we get all the elements that we are going to use for this example, secondly, we are creating the click event listener for the showButton, thirdly we will call the showModal to show our modal with the created form. Notice that we are using the showModal() and not the show() method.

In order to save our selected hero we will listen for the change event of the hero select. When the user changes the selection we will add that value to the confirm button.

Next, we are listening for the close event of the whole dialog, in addition to that we are populating the output box with either No return value or Return Value plus the super hero name.

Last but not least, we are using the click event listener on the confirm button to prevent the form from submitting but also to call the close() method on the dialog element passing it the selected superhero value, which will be used as returnValue in the close() method of the dialog.

On the cancel button, we have used the special attribute formmethod="dialog" which will close the dialog and also set the returnValue to ‘cancel’. Which you can also get from the event object if you use the following code:

e.target.returnValue

How to close dialog or modal by clicking on its ::backdrop

What we want to accomplish here is to check if the backdrop element has been clicked. We can do this by using the click event object and the dialog dimensions. So for the left side, we need to check if the click happens on the X axis that’s less than the point on the screen where the modal starts on the left side.

favDialog.addEventListener('click', (e) => {
  const dialogDimensions = favDialog.getBoundingClientRect()
  if (
    e.clientX < dialogDimensions.left ||
    e.clientX > dialogDimensions.right ||
    e.clientY < dialogDimensions.top ||
    e.clientY > dialogDimensions.bottom
  ) {
    favDialog.close(selectEl.value)
  }
});

Closing HTML5 Modal – Code BreakDown

We are adding a new click listener to the dialog element since the backdrop is its child element but unfortunately, we can’t target it directly. What we can do we can get the dialog’s bounding rectangle. It will give us its position relative to the viewport. Then we can check whether the user clicked on the backdrop or not. The image below although not 100% accurate, since dimensions will vary from screen to screen explains really well what the clientX or clientY should be in order to close the modal.

How to close the new html <dialog> tag by clicking on its ::backdrop
Explanation of how we can close the modal by clicking on its backdrop.

Conclusion

It was about time, I am so happy that we can do this since we can do it without adding any extra library. I mean maybe the modals from Bootstrap or Flowbite look better, and if you are already including those in your project you can obviously use theirs. But for some projects where you are not using any library, this is really great!

Create the modal using HTML 5, Vanilla JS and CSS, that closes on outside click!

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top