What's New in HTML 5.2? Hint: Native Modals and More...

HTML 5.2

HTML 5.2 is finally here (meaning that web browsers will begin supporting the specification very soon, if they haven't already). What's new? What's disappeared? Today we'll be discussing the flagship feature of HTML 5.2 (the <dialog> element), what's been stripped away from the specification, and a couple of other cool things that should be getting some love from web browsers now that HTML 5.2 has officially been endorsed by the guys at W3C.

While there are additional areas of interest from the specification that won't be mentioned here, this is everything that you'll find relevant. You can read the full spec here.

Native Modals (the <dialog> element)

Even though native modals have been around for a while now, features like this rarely see any real support from web browsers until the W3C officially approves it. For example, here's an article from mid-2015 where Envato first talked about the <dialog> element. At the time, only Opera and Chrome supported it, meaning we couldn't really implement it into our web designs.

But what is it, exactly?

Okay, so <dialog> is hidden by default:

<dialog>  
  <p>Nobody can see this</p>
</dialog>  

With some JavaScript we can reveal the modal (and then hide it again):

<script> 

const dialog = document.getElementsByTagName("dialog");

dialog.show(); // or dialog.showModal();  
dialog.close(); // attach these to a click event

</script>  

A visible <dialog> modal looks like this:

<dialog open>  
  <p>People can see it now</p>
</dialog>  

It works in both Opera and Chrome, and support is on its way for Firefox and other web browsers. There's even a new CSS psuedo-element called ::backdrop that lets you style the backdrop of the modal, although this only works when the modal is made visible via .showModal(); rather than .show(); (the difference is that showModal automatically comes with CSS styles such as position:absolute, top:0 and left:0 already defined, whereas .show(); will require manual styling). Also, with .showModal();, the z-index CSS property can't be changed. It's up to you which method you like best, both are more than suitable.

You can totally use CSS transition: with <dialog>, but you'll need to add visibility:hidden and visibility:visible before and after the transition.

Multiple <main> Elements

Before, having multiple <main> elements was invalid.

Now it's valid, due to the rise of web apps that may want to implement multiple <main> elements on a single webpage, however the rule is, that only one can be visible on the screen.

Here's what the markup should look like:

<main>Visible</main>  
<main hidden>Not visible</main>  
<main hidden>Not visible</main>  

But this would be invalid:

<main>Visible</main>  
<main>Visible</main>  
<main>Visible</main>  

Styles Within <body>

You can now insert inline CSS styles into HTML, although it should be noted that CSS in the <head> is still better for performance reasons, especially when it's external CSS.

<body>  
    <p>Will be violet</p>
    <style>
        p { color: violet; }
    </style>
</body>  

We've actually been able to do this for a long time, however, the implementation is now valid according to the W3C specification. It should be noted that CSS code implemented in this way is not scoped, so the use-case is rather limited. In the example below, for instance, all of the <p> tags will be colored violet, even the ones nested inside the <header> and <main> tags.

Long story short: doesn't do what you think it should do.

<body>

    <header>
        <p>Will be violet</p>
    </header>

    <main>
        <p>Will be violet</p>
    </main>

    <p>Will be violet</p>
    <style>
        p { color: violet; }
    </style>

</body>  

<legend> Can Now Have Children

Let's say that you have your form fields grouped, because the form is somewhat long. Before, you'd have something like this (below), where the <legend> tag acts as a fieldset heading:

<fieldset>  
    <legend>Credit card information</legend>
    <!-- form fields -->
</fieldset>  
<fieldset>  
    <legend>Delivery information</legend>
    <!-- form fields -->
</fieldset>  

But, what if you had some styles already defined for headings that you wanted to use inside the <legend>, for example <h2> or <h3>? Now that would perfectly valid, however in HTML 5.1 the <legend> tag could only contain text. It's only a minor improvement to the HTML spec, but it's an improvement nonetheless. Here's what the code could look like now:

<fieldset>  
    <legend><h2>Credit card information</h2></legend>
    <!-- form fields -->
</fieldset>  
<fieldset>  
    <legend><h2>Delivery information</h2></legend>
    <!-- form fields -->
</fieldset>  

Goodbye <menu>

Although there's no clear indication as to why, but the <menu> element has been dropped from the specification (it could be due to its confusion with <nav>), so eventually web browsers will stop supporting it. I would recommend that you use <nav> exclusively from now on, and remove any instances of <menu> in your websites. An applicable use-case for <nav> could be the core navigation, a segmented control, a footer navigation, or even a pair of split buttons.

Goodbye Strict Doctypes

Strict HTML doctypes are also invalid now (yes, finally!), although it's highly likely that you haven't used one in years! A moment of silence (and nostalgia) for strict doctypes please!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Okay, moment over—man, that was some ugly code!

Recommended HTML5 alternative:

<!DOCTYPE html>

Much nicer.