1. Web Design
  2. HTML/CSS
  3. HTML

Native Popups and Modals With the HTML5 “dialog” Element

Scroll to top
This post is part of a series called Strange and Unusual HTML.
Meta Tags and SEO
HTML5 Form Validation With the “pattern” Attribute

Many processes on the web these days require users’ full consent in order to be completed. For example, users may need to remove an account, change their username, or confirm a monetary transaction.

A common UX approach in such cases is to display a dialog box, typically with two buttons; one for cancelling and one for proceeding with the action. We have been relying on JavaScript libraries to do this for years, however in this tutorial we’re going to do things natively with the experimental <dialog> element.

Using the Dialog Element

<dialog> is an HTML5 (5.1 to be exact) element. It’s classified as a ”sectioning root", similar to the <body>, <blockquote>, and the <details> elements, each of which establishes a new content section independently. You can place it as a child of the body, or nest it within an element like a <div> or <section>–both approaches are valid.

1
<body>
2
	
3
	<div>
4
		<dialog></dialog>
5
	</div>
6
	
7
	<section>
8
		<dialog></dialog>
9
	</section>
10
11
	<dialog></dialog>	
12
</body>

Supporting browsers (Chrome 37+ and Opera 27+) will render the <dialog> element hidden by default, only making it visible upon request with JavaScript using show() or showModal(), and the close() method to hide it again. Usually, we would run this method within a click event, like so:

1
var $accountDelete = $('#delete-account'),
2
    $accountDeleteDialog = $('#confirm-delete');
3
4
	  $accountDelete.on('click', function() {
5
	    $accountDeleteDialog[0].showModal();
6
	  });
7
8
	  $('#cancel').on('click', function() {
9
	    $accountDeleteDialog[0].close();
10
	  });

The show() v. showModal() Method

It is worth noting that show() and showModal() behave differently.

The show() method reveals the element in accordance to its position in the DOM flow. If you added it immediately before the body closing tag, it may appear at the bottom of the web page. We would have to add customized styles to adjust its position, for example, if we want to place it centered on the page. These styles would typically use z-index to stack the element on top of the other elements, the position property set to absolute, along with left and top.

The showModal() method, on the other hand, will display the element as a modal. It will be displayed at the center of the page by default, and it resides in the top layer, like the fullScreen API which prevents interference by z-index, relative position and overflow of the parent element.

In most cases, it is likely that we would use the convenience of showModal() instead of the show() method.

Customizing Styles

The dialog box carries the browsers’ default style which can be easily overridden like most other elements. You may, for example, make the dialog box border thinner, make the corners rounded, and add drop shadow.

In addition, when the <dialog> element is shown as a modal (using the showModal() method), we have an additional pseudo-element, ::backdrop, at our disposal. The ::backdrop element resides immediately below the dialog box, covering the whole viewport and the rest of the elements beneath.

It is common to style the backdrop with a low opacity dark color–click the red button to see it in action:

Adding Flair with Transitions

Customizing the dialog box styles should be straightforward, but what about adding CSS transition? How about we gradually reveal the dialog box, using a scaling effect, more or less how OS X does it?

Step 1

To begin with, we’ll scale the dialog down by 90%, specify the transition, and put it out of sight.

1
dialog {
2
	visibility: hidden;
3
	transform: scale(0.1);
4
	transition: transform 200ms;
5
}

Step 2

Now we define a class selector that will scale the dialog box up to its intended size and make it visible.

1
dialog.dialog-scale {
2
	visibility: visible;
3
	transform: scale(1);
4
}

Step 3

Our trick now is that we will “hold” the dialog box at its small scale for a few milliseconds before we add the class dialog-scale. To achieve this we use JavaScript’s setTimeout() method to add the class:

1
var transition;
2
3
$accountDelete.on('click', function() {
4
	$accountDeleteDialog[0].showModal();
5
	transition = setTimeout(function() {
6
	    $accountDeleteDialog.addClass('dialog-scale');
7
	}, 0.5);
8
});

Step 4

Let’s not forget to remove this class and clear the timeOut when the dialog box is closed.

1
$('#cancel').on('click', function() {
2
	$accountDeleteDialog[0].close();
3
	$accountDeleteDialog.removeClass('dialog-scale');
4
	clearTimeout(transition);
5
});

We are all set! You can give it a ride in the following demo:

Wrapping Up

The <dialog> is really handy, though still very poor in regard to browser support. If and when all major browsers have implemented it, we will be less reliant on libraries, our content structure will be more semantic, properly accessible to assistive technology, and we’ll have a standard way of delivering modal dialogs.

caniuse dialogcaniuse dialogcaniuse dialog
http://caniuse.com/#feat=dialog

Until then, you can use the polyfill from Google Chrome to simulate it in non-supporting browsers.

Further Resources

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.