Mathias Bynens

The three levels of HTML5 usage

Published · tagged with HTML

I was asked to give an introductory talk on HTML5 for the latest Adobe User Group Belgium Web SIG Event. The presentation I ended up with is entitled “HTML5: It goes to ELEVEN” and can be viewed on Slideshare.

Since the target audience was filled with ‘esteemed HTML5 newcomers’ I decided to focus on how easy it is to ‘switch’ to HTML5 and use it today. The way I see it, there are three levels of HTML5 usage:

Level 1: It Just Works™

The HTML5 spec is written (and still being edited) with backwards compatibility in mind. There are some new features in HTML5 that already work in every A-grade browser and can thus be used today, without requiring any weird hacks. Level 1 HTML5 is limited to these features.

Redefined HTML4 elements

Some HTML4 elements were changed in HTML5. Because these elements already existed before HTML5 and have been around for a while, all browsers already support them. You really don’t have to do anything to benefit from their new meaning and added possibilities in HTML5.

Most of the changed HTML elements simply get new semantics, but one of them gets a new ‘feature’ — the a element, used to create hyperlink anchors or ‘links’. In HTML4, you were limited to inline links (in phrase content), but HTML5 makes it possible to use block level links, meaning you can use the a element as if it was a clickable div:

<a href="/canhazfood/carrot">
<h1>Carrot</h1>
<p>Om nom nom nom.</p>
</a>

After that, all you need is some extra CSS on the anchor:

a {
display: block;
}

Simplified syntax

HTML5 greatly simplifies the general syntax of your documents. This makes HTML5 easier to use than any of its predecessors.

DOCTYPE

I bet 99% of all web developers never typed out a pre-HTML5 DOCTYPE declaration. Either they copy-pasted it, or had it inserted automatically by their editor of choice. You can’t blame them — no one likes to type out stuff like <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "https://www.w3.org/TR/html4/strict.dtd">.

The HTML5 DOCTYPE, on the other hand, is short, simple, and easy to remember:

<!DOCTYPE html>

You’ll probably spend more time copy-pasting that than simply typing it out. Did I mention the new, shorter DOCTYPE also avoids potential security issues in Internet Explorer? Start using it now, and never look back.

Character encoding

Specifying a document’s character encoding gets easier, too. Instead of…

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

…you can just use the following in HTML5:

<meta charset="utf-8">

Optional type attributes

HTML5 specifies default values for the type attribute on script, style, input, and link elements with rel="stylesheet". Unless you need a different value than the default, you can simply omit the type attribute.

<!-- HTML 4.01 / XHTML -->
<link rel="stylesheet" type="text/css" href="foo.css">
<!-- HTML5 -->
<link rel="stylesheet" href="foo.css">
<!-- HTML 4.01 / XHTML -->
<script type="text/javascript" src="foo.js"></script>
<!-- HTML5 -->
<script src="foo.js"></script>
<!-- HTML 4.01 / XHTML -->
<style type="text/css">
body { background: gray url(boring.gif) no-repeat; }
</style>
<!-- HTML5 -->
<style>
body { background: pink url(unicorns.png) repeat; }
</style>
<!-- HTML 4.01 / XHTML -->
<input type="text">
<!-- HTML5 -->
<input>

Optional solidus (/>)

The most distinct difference between HTML4 and XHTML is that the latter requires a stricter syntax for self-closing elements. In XHTML, this is how you insert an image:

<img src="foo.png" alt="Foo" />

The space is optional, so the following is valid XHTML as well:

<img src="foo.png" alt="Foo"/>

However, in HTML, using the solidus isn’t required:

<img src="foo.png" alt="Foo">

For backwards compatibility, HTML5 accepts all of the above syntax variations. This makes it very easy to ‘upgrade’ your valid HTML4 or XHTML documents to HTML5. Just change the DOCTYPE and boom! — you’ve got yourself a valid and conforming HTML5 document. Yay for backwards compatibility!

Level 2: Stuff that degrades gracefully by default

HTML5 has some slightly more advanced features than those in Level 1. These features can be used without a problem, and will work in modern browsers who support them. In older browsers, they won’t work out-of-the-box, but at least nothing will break — all non-HTML5 functionality will be preserved.

The most obvious examples of this were described in the Web Forms 2.0 spec, which is now superseded by the Forms chapter of the HTML5 specification. HTML5 offers new values for the type attribute on input elements. For example, for email input fields, you can use:

<input type="email">

This is especially advantageous on mobile devices, who can provide an optimized keyboard layout for entering an email address (with dedicated keys for the @ and . characters). The same goes for the other new input types: there’s url for URLs, tel for telephone numbers, number for numbers in general, datetime, date, time, month, week and many, many more.

There are some new attributes for input elements as well. placeholder allows you to specify a short hint (a word or short phrase) intended to aid the user with data entry. Browsers that support it, will display the placeholder text when the input element’s value is empty and doesn’t have focus.

<input type="email" placeholder="bazinga@example.com">

The autofocus attribute indicates that an input field should receive focus upon page load.

<input type="search" autofocus>

You can just go ahead and use the new input types and attributes. Users with modern browsers will immediately benefit from the advantages; everyone else will simply get the same experience as they would without the added HTML5 goodness. If you enter an unknown value for the type attribute on an input element, or omit it altogether, browsers will interpret it as if it was text. Similarly, if a browser encounters an unknown attribute, it will simply ignore it.

Sometimes, graceful degradation just isn’t enough — if you want to use the new placeholder and autofocus attributes and have them work in Internet Explorer, for example. You’ll have to use feature detection through JavaScript and provide a fallback emulating the desired behavior.

Level 3: All you need is some extra love

So far we’ve seen two levels of HTML5 usage: Level 1 (new HTML5 goodness that just works) and Level 2 (stuff that degrades gracefully by default). Every new HTML5 feature that wasn’t already mentioned, is part of Level 3. Sadly, these features require additional hacks to work cross-browser. Forget about graceful degradation — these are things that mess your site up if you don’t provide proper fixes.

New elements

HTML5 offers three types of new elements: sectioning elements, inline elements and interactive elements.

The new sectioning elements are <section>, <article>, <nav>, <aside>. There are some ‘flow content’ elements that can be used to indicate page sections as well: <header> and <footer>. These elements provide semantic alternatives to what used to be <div>s in HTML4 documents. This doesn’t mean <div>s are deprecated in HTML5 — you just won’t need them anymore to mark up these common document portions.

Since these new block-level elements aren’t yet included in most user agent stylesheets, you’ll just have to add some CSS to make them work as intended:

article, aside, footer, header, section {
display: block;
}

Of course, this is just an example using the most common new block-level HTML5 elements, but you get the idea.

Some of the new inline elements are <mark>, which indicates a highlighted run of text, and <time>, which is pretty self-explanatory. Again, these elements can be seen as semantic alternatives to certain situations where you’d probably use <span>s in HTML4.

When Internet Explorer encounters an element that it doesn’t recognize, it doesn’t apply any CSS on it. However, this can easily be fixed by using the HTML5 shiv (JavaScript), effectively eliminating the need to avoid new elements that don’t require special rendering or user interaction.

The new interactive elements in HTML5 are elements like <details> and <video>. Obviously, if you want to use these in a cross-browser-compatible way, some more work is needed. Sure, with the above fix, these elements can be styled using CSS in every browser — but still, not all browsers known how to handle them. The key here is to use feature detection with JavaScript and provide a fallback (in JavaScript and/or Flash) if needed. Of course, you’ll need different feature tests and fallbacks for different elements, but the good news is: you probably won’t have to code these yourself. For example, not too long ago, I wrote about a bulletproof HTML5 <details> fallback using jQuery.

JavaScript APIs

As with the new interactive elements, the new HTML5 JavaScript APIs (for <video>, <audio>, <canvas>, drag-and-drop, offline apps, inline editing, workers, web sockets, and many more) won’t just work in browsers that don’t support them. You’ll need to use feature testing and provide a fallback in JavaScript and/or Flash when needed.

Browser support tables, feature tests, shims, polyfills, fallbacks, and further advice

Once you’ve pinned down which HTML5 feature you want to use, you may want to find out which browsers already natively support it. In that case, just look it up on When Can I Use.

Looking for a feature test? Check The All-In-One Almost-Alphabetical No-Bullshit Guide to Detecting Everything, or just use Modernizr for all your feature detection needs.

Looking for a fallback, shim or polyfill? Check the Modernizr wiki.

Looking for advice on a specific feature? HTML5 Please is here to help.

Summary (TL;DR)

There is no reason not to use Level 1 HTML5. It works in every browser, you can do cool stuff that wasn’t allowed before (like using block level anchors) and the general syntax is easier than the HTML 4.01 / XHTML you were using before.

Level 2 offers some nice little extras over HTML4/XHTML. They might not be supported in all current browsers yet, but at least using them won’t break anything. It’s possible to emulate the desired behavior in older browsers using JavaScript anyway.

The Level 3 HTML5 features only work in browsers that support it; in older browsers, there’s no graceful degradation by default. It just won’t work. You’ll have to use JavaScript for feature detection and provide a fallback of your own when needed. Needless to say, this level is the most fun for hardcore web developers living on the edge :)

If you need a browser support table, a feature test, a fallback, or just some advice on a specific HTML5 feature, an excellent set of resources is at your disposal.

About me

Hi there! I’m Mathias. I work on Chrome DevTools and the V8 JavaScript engine at Google. HTML, CSS, JavaScript, Unicode, performance, and security get me excited. Follow me on Twitter, Mastodon, and GitHub.

Comments

James Britt wrote on :

First, I had no idea that /> had a name. Solidus.

Second, the article is unclear on the ‘optional’ nature of the solidus. I’m pretty sure that the use of the solidus depends on whether you are using an HTML or XHTML serialization.

  • If you are sending the page with Content-Type: text/html, you need to follow HTML format and leave out the solidus (that is, you follow the same rules as you would for HTML4).
  • If you are using the XHTML serialization you need to be using XML syntax and send the page as application/xml or application/xhtml+xml.

wrote on :

Nope, that’s the whole point. You’re free to use the solidus in the HTML serialization of HTML5. In the XHTML serialization of HTML5, the solidus isn’t required either; you can choose to close the elements instead.

The following examples are both confirming/valid HTML5 in ‘XML mode’ (they’re valid XHTML1 as well).

With solidus:

<img src="foo" alt="bar" />

Without solidus:

<img src="foo" alt="bar"></img>

Just to be clear though, in my post I was just pointing out that you don’t have to change anything in your HTML4/XHTML code to switch to HTML5, except for the DOCTYPE.

James Britt wrote on :

Thanks for the update.

Some additional info here: https://www.w3.org/TR/html5/syntax.html#void-elements

I’m skeptical about the increased casual nature of what makes for an acceptable HTML-serialized HTML5 doc. Seems it just makes it that much harder to write a robust parser and tools. Especially the continued use of empty attribute syntax, which is just nasty. I understand it’s to allow plain old HTML docs to be acceptable, but still…

Martin wrote on :

Nice article.

I’m searching how is the best way to develop an entire site using HTML5, but compatible with not-HTML5 browsers. I don’t like 2 versions idea, or Chrome Frame.

TomkOx wrote on :

Non-compatible with HTML5 is Internet Explorer only. If you wanna serve sites also to Microsoft fans, you should make sites twice :) For normal browsers (in the HTML) and for idiot’s browser (in a MS-penised-HTML).

charly wrote on :

Thanks! Very useful for transitioning smoothly to HTML5. Knew all the new features but never dared using any, just couldn’t bother making out what was safe or not for my non-tech-savvy websites with IE users. That solved the issue!

jahewson wrote on :

TL;DR: It’s a slash, not a solidus.

Unicode actually gets it wrong: the character / (U+002F SOLIDUS) is not a solidus at all, it is a (forward) slash. A solidus has a much more shallow angle and was used as a separator in old British currency, and is still used in Mathematics. Ironically the Unicode character for an actual solidus is U+2044 FRACTION SLASH. Here’s some history: http://www.princeton.edu/~achaney/tmve/wiki100k/docs/Solidus_(punctuation).html.

NickA wrote on :

Small typo:

However, in HTML, using the solidus isn’t required […]

…should be:

However, in HTML5, using the solidus isn’t required […]

Mad Myche wrote on :

The solidus/slash was NOT allowed in HTML4, therefore HTML5 allowing it technically is not backwards compatible — rather it allows the mutt known as XHTML back into the main family tree.

wrote on :

Mad: HTML4 (just like any other version of HTML) didn’t require the solidus, so yes, HTML validators throw an error if they encounter one in an HTML4 document.

However, browsers never cared. They never did anything special when such a solidus was encountered; not for XHTML documents, and not for HTML documents. As such, backwards compatibility is not an issue. HTML5 allowing either syntax is simply a case of paving the cowpaths: allowing things that were being done anyway (despite being technically invalid) and that browsers supported anyway.

MarkH wrote on :

The whole discussion can be summed up as “all squares are quadrilaterals but not all quadrilaterals are squares”.

Solidus or closing tags on void elements are optional for HTML5—they cause no harm but are not required. But XML always requires them. Basically, XHTML5 is always valid HTML5 when you put in the DOCTYPE correctly, zero changes are required to switch between HTML5 and XHTML5—how it is treated is solely determined by the MIME type. However, if you decide to drop the formalities of well-formed XML and merely stick to HTML5 then you have work to do if you ever want your document to be valid XML.

The powers that be who established the HTML5/XHTML5 standard did this deliberately to directly address the concern and problems caused by the poor practice of serving up XHTML (1.x) with the HTML MIME type (something Microsoft irresponsibly encouraged by neglecting standards conformance in the IE browser). This ‘cowpath’ was paved for good reason, as the destination of the cowpath is an XML conformant document that can be processed without consequence as an alternative MIME type without “breaking the rules”. If there wasn’t a benefit to coding XHTML then why would it be formally codified into the (x)HTML5 standard then?

That is why I go to all lengths to make sure I always conform to XML requirements in HTML5 documents, even if my document is being served and parsed as HTML5 rather than XHTML5. Doing so keeps all options open, and coding to HTML5 is a dead-end—a problem waiting to surface once you go beyond serving content to a human running a browser. Such benefits to writing XML-conformant HTML5 (aka XHTML5):

  1. Parsing and rendering XHTML5 is far more straightforward, less intensive and more consistent. If you do something wrong you get the “yellow screen of death” — that is a feature, not a bug. The strictness of XML parsing is more dependable than any online HTML validator out there for keeping the source of your document clean.
  2. XHTML5 enables the benefits of XML in addition to HTML5 compatability so you can put SVG, MathML or any other XML based markup in your document properly.
  3. People with a programming background will appreciate the superior maintainabiltiy and readability of XHTML5 over HTML5. Web ‘designers’ don’t care—they use ‘tools’ that generate this code goes the argument. If they need to hack some HTNL code up, they all too often want to be ‘lazy’ and call for all sorts of flexibility so they can forget to close tags or turn off the caps lock ot forget quotes and not worry about breaking things. But this flexibility creates ambiguity and it can be much better for things to break than to ‘sort of’ work because of browsers’ assumptions.
  4. There is a whole other level of XML processing tools out there that are not available to HTML that is not XML conformant. The same XHTML5 document used to show a pretty page on a browser can act as data to be processed in machine-to-machine communication using XSLT and all sorts of XML processing libraries. Yes, you can use XSLT to output non-XML, but you need XML-conformant files like XHTML5 to be the input to XSLT.

The whole situation that has come about is not the fault of web page ‘designers’ — the laziness is not because of their character or personality, it is because for two decades they have been told being lazy is OK, HTML parsers have been very loose and the whole industry has ‘coddled’ such loose behaviour that would not be accepted in other realms of programming. But authoring websites is programming — it is not just ‘design’ alone, and authors of HTML have to start viewing their output as code in the same way C, Java, (JavaScript even), Python, Perl, PHP etc. are treated (even loosely typed scripting languages demand more structure).

Ian Hickson wrote on :

For the record, the only reason the HTML spec now actually defines XHTML at all is that browsers support it and so it’s important to make sure that they all do it the same way.

Using XML for HTML is a waste of time. It’s not at all the case that any valid XHTML is valid HTML, in fact it’s very hard to make any non-trivial page be both valid HTML and XML and mean the same thing in both. It looks easy, and so many people think it’s easy, but that’s very deceptive.

Dean wrote on :

Thanks for this article, I have been putting off getting too much into HTML5 because I wasn’t sure about backwards compatibility, so this has really helped. Just one thing I wanted to be absolutely clear on — you seem to be saying that I can take any HTML4 document whatsoever (or even prior to 4?), change the doctype to the new HTML5 one, and nothing will go wrong — is that right? I had always thought that older versions of IE relied on the doctype to display some CSS correctly, and that if you missed out the doctype, it would behave unpredictably? Surely that would also be the case for an unknown doctype, which the HTML5 one would be to an older browser. Is that not that case? If it is, how old exactly in terms of IE are we talking about having a problem with? Once again thanks for the article.

Leave a comment

Comment on “The three levels of HTML5 usage”

Your input will be parsed as Markdown.