We’ve covered a lot of ground so far. To recap, HTML5 has four new block-level sectioning elements that we can use to give the parts of web pages more semantic meaning. These new elements are for ‘chunks of related content’—basically a logical section of the document:
-
<section>—a generic chunk of related content
-
<article>—an independent, self-contained chunk of related content, that still makes sense on it’s own
-
<aside>—a chunk of content that is tangentially related to the content that surrounds it, but isn’t essential to understanding that content
-
<nav>—navigation for the site or page
These new sectioning elements should contain a <header> element with the section’s title, and any other introductory information. They can also contain one or more <footer> elements with additional information such as copyright, related links etc. It’s important to note that <header> and <footer> apply to the structural element they’re in—they’re not the same as a page header or page footer. It’s also important to remember that <header> and <footer> can’t contain other <header>s and <footer>s, and <footer> can’t contain heading or sectioning elements. Finally, while the words “header”, “footer” and “aside” all come with preconceptions, their semantic meaning comes from the types of content they contain, not from their presentation or relative placement. For example, an <aside> could contain a footnote, and a <footer> containing a ‘Top of Page’ link could appear at both the top and bottom of a section.
Now let’s look at example structures for a basic article page; using the standard layout of a page header (with logo etc), navigation tabs, a main column, a side column, and a page footer.
Article Page
Here’s the outline of the parts of our page:
- Site header (logo, search, …)
- Site navigation
- Main content (wrapper)
- Main column
- Article
- Article title
- Article metadata
- Article content…
- Sidebar
- Sidebar title
- Sidebar content…
- Footer
So let’s write that in standard HTML4:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Article (HTML4)</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content">
<div id="main">
<h1>Article title</h1>
<p class="meta">Article metadata</p>
<p>Article content…</p>
</div>
<div id="sidebar">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
So let’s write that in standard XHTML1.0:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en">
<head>
<title>Article (XHTML1)</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content">
<div id="main">
<h1>Article title</h1>
<p class="meta">Article metadata</p>
<p>Article content…</p>
</div>
<div id="sidebar">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
Now let’s convert that to HTML5, using the new structural elements:
<!doctype html>
<html lang="en">
<head>
<title>Article (HTML5)</title>
<meta charset="utf-8">
</head>
<body>
<header id="branding">Site logo, search etc</header>
<nav>
<ul>
<li>Site navigation</li>
</ul>
</nav>
<section id="content">
<article>
<header>
<h1>Article title</h1>
<p>Article metadata</p>
</header>
<p>Article content</p>
</article>
<section id="sidebar">
<h2>Sidebar title</h2>
<p>Sidebar content</p>
</section>
</section>
<footer id="footer">Footer</footer>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<title>Article (HTML5)</title>
<meta charset="utf-8" />
</head>
<body>
<header id="branding">Site logo, search etc</header>
<nav>
<ul>
<li>Site navigation</li>
</ul>
</nav>
<section id="content">
<article>
<header>
<h1>Article title</h1>
<p>Article metadata</p>
</header>
<p>Article content</p>
</article>
<section id="sidebar">
<h2>Sidebar title</h2>
<p>Sidebar content</p>
</section>
</section>
<footer id="footer">Footer</footer>
</body>
</html>
Note here we assume that the sidebar contains content not related to the article (such as recent articles etc). If it only contained content tangentially related to the article we could use <aside>. Also we assume that the <footer> doesn’t contain much more than a copyright statement and contact information—a detailed footer with headings etc would need it’s own <section>.
doctype, charset & XHTML-style markup
You’ll notice the doctype and charset are both much simpler. While this style charset is recommended, the pre-HTML5 charset declarations are still valid. Also, if you’re viewing XHTML-style code examples, you’ll note that the charset element still has an XHTML-style trailing slash in the HTML5 example. In fact XHTML-style markup (a closing / on empty elements) like this is also valid HTML5! This makes it very easy to migrate to HTML5 from both HTML and XHTML pages. You should try to avoid mixing HTML and XHTML-style code, however—choose one style and stick with it.
HTML5 or XHTML5? Choose HTML5
If you currently use XHTML1.x you might be thinking to use XHTML5, the XML-compatible version of HTML5. If your website will have a general audience, don’t. XHTML5 must be sent with an XML mime type (like application/xhtml+xml), and even IE8 still doesn’t support this. However, all of the hallmarks of XHTML coding—writing elements in lower case, correct nesting, closing tags, adding optional elements that add meaning—are all compatible (HTML5 is case-insensitive) or encouraged in HTML5.
You’ll notice the charset is simplified. While this style is recommended, the pre-HTML5 charset declarations <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> and <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> are both still valid. Also, if you’re viewing XHTML-style code examples, you’ll note that the charset element still has an XHTML-style trailing slash. In fact XHTML-style markup like this is also valid HTML5! This makes it very easy to migrate to HTML5 from both HTML and XHTML pages. You should try to avoid mixing HTML and XHTML-style code, however—choose one style and stick with it.
Browser support; CSS and JS
So, does it work? Currently the HTML5 structural elements will work in modern browsers (Firefox 3+, Safari 3+, Opera 9+, Chrome 1+) as long as we declare them as block-level elements via this CSS:
article, aside, dialog, figure, footer, header, legend, nav, section {
display: block;
}
and in Internet Explorer 8 and below we need to hack support in via Javascript (I bet you didn’t see that coming ;-)
(function(){if(!0)return;var e = "abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(','),i=e.length;while(i--){document.createElement(e[i])}})()
The recommended way to add this Javascript is via Remy Sharp’s Google Code-hosted HTLM5 shiv for IE in the head:
So, all together now…
<head>
<style type="text/css" media="screen">
article, aside, dialog, figure, footer, header, legend, nav, section {
display: block;
}
</style>
…
</head>
…but IE requiring JS means we’re screwed, right?
You might think that IE’s lack of support without Javascript for these new elements means you can’t use HTML5 at all, but there are two ways we can still benefit from HTML5’s greater semantic richness—by using HTML5 semantic element names as class names on <div>, in either HTML4/XHTML1.0 or HTML5. You’re probably already using a standard set of class and id names anyway, and this is in effect a standardised set of semantic class names. HTML5 is basically a superset of HTML4/XHTML1, so as long as you don’t use any new elements HTML5 pages will work in IE. It also has the benefits of simplifying a future move to HTML5, and if you use the HTML5 doctype you can also use the more detailed HTLM5 validators.
Here’s the HTML4 version using HTML5 class names:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Article (HTML4), with HTML5 class names</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="branding" class="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content" class="section">
<div id="main" class="article">
<div class="header">
<h1>Article title</h1>
<p>Article metadata</p>
</div>
<p>Article content…</p>
</div>
<div id="sidebar" class="section">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
Here’s the XHTML1 version using HTML5 class names:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en">
<head>
<title>Article (XHTML1), with HTML5 class names</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="branding" class="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content" class="section">
<div id="main" class="article">
<div class="header">
<h1>Article title</h1>
<p>Article metadata</p>
</div>
<p>Article content…</p>
</div>
<div id="sidebar" class="section">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
Now in HTML5, again using <div> with HTML5 class names rather than the new HTML5 elements:
<!doctype html>
<html lang="en">
<head>
<title>Article (HTML5), with HTML5 class names</title>
<meta charset="utf-8">
</head>
<body>
<div id="branding" class="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content" class="section">
<div id="main" class="article">
<div class="header">
<h1>Article title</h1>
<p>Article metadata</p>
</div>
<p>Article content…</p>
</div>
<div id="sidebar" class="section">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<title>Article (HTML5), with HTML5 class names</title>
<meta charset="utf-8" />
</head>
<body>
<div id="branding" class="header">Site logo, search etc</div>
<ul id="nav">
<li>Site navigation</li>
</ul>
<div id="content" class="section">
<div id="main" class="article">
<div class="header">
<h1>Article title</h1>
<p>Article metadata</p>
</div>
<p>Article content…</p>
</div>
<div id="sidebar" class="section">
<h2>Sidebar title</h2>
<p>Sidebar content…</p>
</div>
</div>
<div id="footer">Footer</div>
</body>
</html>
You may be wondering why these two examples are so similar—after all, only the doctype and charset differ! That’s because one of HTML5’s core principles is compatibility. If we don’t use any new HTML5 elements, a change of doctype might be all that’s required to convert a well-coded HTML or XHTML page to HTML5.
Why bother with HTML5?
So if you’re not going to use HTML5’s new elements, which IE doesn’t support without Javascript, what’s the point of thinking about HTML5 now? I see several benefits:
- Thinking about HTML5’s structural elements (even if we only express the semantics via class names) will make our code more logical and semantic
-
HTML5 is defined in far greater detail than previous HTML/XHTML specs, giving us more guidance in creating web pages
- Another benefit of this detail is more accurate validators (W3C, Validator.nu), with the potential for more detailed error messages
- If you think you might convert to HTML5 in the future, the HTML5-elements-as-class-names approach and a little regexp magic should remove a lot of the pain of converting
- Now that XHTML2 development will be halted, starting to learn about the official future of HTML is a good idea
- Using HTML5 is a sliding scale, not all or nothing. You can get benefits from simply changing the
doctype, a five second job.
- Because browsers use the same parser for HTML5 as HTML4/XHTML1, and because backwards compatibility is a central tenet, using an HTML5
doctype today has almost no disadvantages (make sure to check HTML5 differences from HTML4, specifically 3.3-3.5).
It’s possible to just change the doctype and get some benefits from having converted to HTML5 (when you use a validator :). However, the more time you put into HTML5 the greater the reward. You’ll get the most benefit from rethinking your site’s semantics from an HTML5 perspective, although for the present I’d recommend adding these extra semantics via the HTML5-elements-as-class-names approach.
While it’s possible to just change the doctype and correct any validation errors when converting to HTML5, you’ll get the most benefit from rethinking your site’s semantics from an HTML5 perspective.
Questions? Feedback? Mistakes? Let me know via Twitter (@boblet)…