Advertisement

How to Make All Browsers Render HTML5 Mark-up Correctly - Even IE6

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

This post is part of a series called HTML5 and You.
Quick Tip: New HTML5 Form Features
HTML5 Audio and Video: What you Must Know

HTML 5 provides some great new features for web designers who want to code readable, semantically-meaningful layouts. However, support for HTML 5 is still evolving, and Internet Explorer is the last to add support. In this tutorial, we'll create a common layout using some of HTML 5's new semantic elements, then use JavaScript and CSS to make our design backwards-compatible with Internet Explorer. Yes, even IE 6.


Tutorial Details

  • Technology: HTML
  • Version: 5
  • Difficulty: Intermediate
  • Estimated Completion Time: 1 hour

Prefer a Video Tutorial?

Quick Overview of HTML 5 Elements

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 for you to read and organize your code, and makes it easier for search engines and screen readers to read and
organize your content.

The HTML 5 elements we'll be using are:

  • header
  • footer
  • nav
  • article
  • hgroup

Just by reading the names of the elements, you should get a pretty good idea of what they're for, and that's the point!
You can now stop abusing <div> in all your tableless designs, and instead make headers out of "<header>"s and
footers out of "<footer>"s.

The one element that may not be obvious is <hgroup>. This element simply defines a group of header elements (<h1>
- <h6>) so you can group a blog post title and subtitle together, for example. Think of it as not the header of the page,
but the header of the content section.

Step 1: The HTML

We're going to recreate the most common layout on the Web, the 2-column layout:

This layout is usually put together with a waterfall of <div> elements (or, shudder, a <table>), but with HTML 5
you can code this page quite naturally.

	<!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>

And to round it out, within the "main" element, I'm going to add some simple post templates:

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

Now we have an entire layout skeleton in HTML that uses nothing but meaningful tags for all the content. Easy to read,
easy to parse, easy to design for.

Some savvier readers may ask "why didn't you use <section> instead of a <div> for the main column? Wouldn't that
be more "meaningful?" You certainly could, and it would be "valid," but the <section> element isn't meant for this
sort of layout function. From the spec:

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.

Step 2: The CSS

Positioning these elements would be easy if they were all <div>s — we know how they are handled by every browser, so
we know how to write CSS to them. However, this is only the case because every browser applies a default stylesheet to a page.
Even if you haven't specified one, there is CSS at work every time a page you've written gets loaded into Firefox or IE.

For example, here's the styling applied to a <div> in the default "html.css" file that comes with Firefox:

	html, div, map, dt, isindex, form {
		display: block;
	}

But what happens when a browser comes across an element that it doesn't recognize? We can't be sure. It might get no styling,
it might inherit a some default styling, it might not be displayed at all. Therefore, we make sure that we account for any and
all styling of our new elements in our own CSS. No assumptions.

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

Now we can treat these elements just like <div>s, assured they are displayed consistently.

The Problem

Let's take a look at our layout so far. I've put together a more fleshed out version of this code and tested it in
a few browsers. Check out our layout in Safari 4:

However, look at what happens in Internet Explorer 6:

What's wrong with this picture? 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 recognize, 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.

Step 3: The JavaScript

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."

It simply involves calling document.createElement() for every new, unrecognized 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");

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...

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

Perfect. Internet Explorer 6 is now rendering HTML 5 code just as well as Safari 4.

Conclusion

HTML 5 is exciting for any web designer 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.

Got any more tips for squeezing every bit of HTML 5 you can into your production code? Let us know in the comments!

Write a Plus Tutorial

Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We're looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you're of the ability, please contact Jeffrey at nettuts@tutsplus.com.

Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

Write a PLUS tutorial
Advertisement