HTML5 Semantic Markup

Supported Browsers: Opera 10.6+, Firefox 3.5+, Safari 3.2+, IE 9.0+, Chrome 9.0+, iPhone 3.2+, Android 2.1+

By Alexander Jones,

Introduction

The first thing to think about when getting started with HTML5 is changing to the new doctype, which should be on the first line of every HTML page. In HTML5 there is only one doctype:

<!DOCTYPE html>
<!-- Everything else goes in here -->
<!-- Ending with the closing tag: -->
</html>

1. Overall Structure

The HTML 5 Working Draft provides a new set of semantically-meaningful elements for describing a typical web page layout. Using elements that are "meaningful" (i.e. describe the content they contain) makes it easier to read and organise code, and makes it easier for search engines and screen readers to read and organise the content of a site.

The HTML 5 semantic elements are:

<header>, <footer>, <nav>, <article> and <hgroup>

Now instead of using <divs> to position the structure of a web site design, the footers can be made out of <footer>'s and the header's out of <headers>'s.

These elements are put together naturally to create a standard 2-column layout, the tags make sense and have meaning:

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<html>
  <head>
	<title><!-- Your Title --></title>
  </head>
 <body>
    <header>
     <!-- ... -->
    </header>
    <nav>
     <!-- ... -->
    </nav>
    <div id="main">
     <!-- ... -->
    </div>
    <footer>
     <!-- ... -->
    </footer>
 </body>
</html>

To structure the content of "main" some more elements can be added, typical templates consist of the following:

<article>
  <hgroup>
    <h2>Title</h2>
    <h3>Subtitle</h3>
  </hgroup>
  <p>
    <!-- --->
  </p>
</article>

The Section Tag

One important point to mention about the layout above is why a <div> element has been used for "main" rather than one of the new <section> tags. as it would be more meaningful mark-up. But accoding the current HTML5 spec the <section> tag is not meant for this:

The section element is not a generic container element. When an element is needed for styling purposes or as a convenience for scripting, authors are encouraged to use the <div> element instead. A general rule is that the section element is appropriate only if the element’s contents would be listed explicitly in the document’s outline.

2. The CSS

If the elements were all <div>'s then it would be easy to position the website as it's known how they are handled by different browsers. This is the case because each browser applies its own default stylesheet to a page.

If a browser does not recognise an element, it may get some styling or possibly none at all. Therefore, it's important to account for these different browsers and not to make any assumptions so we style all elements in our own CSS:

/* Make HTML 5 elements display block-level for consistent styling */
header, nav, article, footer, address {
	display: block;
}

A look at the layout so far with some applied styling and content and having been tested in a few browsers, the layout in Google Chrome is shown below:

Chrome pic
HTML5 elements tested in Chrome

3. IE Problems

However in IE 8 and below, this is what happens:

IE pic
HTML5 elements tested in IE8

What’s wrong with this screenshot in IE? By explicitly setting display: block; in CSS, we should have communicated to the browser our intentions for that element. Unfortunately, IE is ignoring elements it doesn’t recognise, regardless of CSS. Our content is left floating in its parent’s container, as if the HTML 5 elements didn’t exist.
Somehow, we need to get IE to render unknown elements, and styling them appropriately isn’t going to do it.

4. The JavaScript Fix

Luckily, there is a way to get IE to recognize new elements via some simple JavaScript.
I first read about this technique on John Resig’s blog; he’s called it the "HTML 5 Shiv".

resig pic
The HTML5 Shiv

It simply involves calling document.createElement() for every new, unrecognised element.

Traditionally you’d make this call in order to inject an element directly into some branch of the DOM; in other words,
into an existing container within the <body> tag. You can do that to fix this unknown element issue as well. However,
this trick also works by calling document.createElement() in the <head> tag, with no refence to a containing element!
That makes it much easier to read and write:

document.createElement("article");
document.createElement("footer");
document.createElement("header");
document.createElement("hgroup");
document.createElement("nav");

Remy Sharps HTML5 Enabling Script

To make things even more convenient, Remy Sharp has released an “HTML 5 Enabling Script,” which does the same thing as our code above, but for all HTML 5 elements.

Since HTML5 is getting more attention by way of marking up our new pages, and the only way to get IE to acknowledge the new elements, such as <article>, is to use the HTML5 shiv, I’ve quickly put together a mini script that enables all the new elements… Remy Sharp

Now that we’ve added our JavaScript, let’s look at that again in Internet Explorer, with our new JS code:

IE with shiv pic
IE8 with the applied HTML5 Shiv

Perfect. Internet Explorer 6 and above is now rendering HTML 5 code just as well as Safari 4 and Chrome.
You can view the page here to see for yourself!

6. Conclusion

HTML 5 is exciting for any web developer who wants to create clean, easy-to-read, semantically-meaningful code. And with just a couple of simple steps — one line of CSS and one line of JS per element — we can start making use of HTML 5 today.

The Next Step

The next step is to go out and develop! Try different things and experiment with forms, there's a huge wealth of features to get stuck into not to mention CSS3 styling that can applied to give even more functionality, for more information on HTML5 forms, be sure to get check out these great resources: