How to Make All Browsers Render HTML5 Mark-up Correctly – Even IE6
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.

- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web.













It appears that there is a missing { in the css for the very last style.
Also, isn’t starting the document with and redundant?
Ugh. cCode doesn’t show up. My last sentence refered to the doctype being html and then having another tag be html. Can the document just start with the first html in the doctype, then start the head tag, and then the meta tag?
The Doctype is not a tag, its just a declaration about the version of HTML that the document is adhering to. I think W3C has a very long plan with HTML 5; so the HTML 5 doctype is just and something like !! AFAIK the doctype declaration should be case sensitive…..
Your avatar is very nice
….. the HTML 5 doctype is just <!DOCTYPE HTML> HTML and not something like <!DOCTYPE HTML> …..
HTML 5 looks promising.
Thanks for this, very usefully tutorial – great job!
I noticed a lot of people are iffy about this method simply because it employs javascript, which they say you should never rely on since someone might have it disabled. Sorry, but those people need to get with the program. Literally. Javascript is everywhere and in almost every site that does anything beyond saying “hi.” Not having javascript enabled is a few steps shy of turning off the internet.
p.s. After nearly 12 years of knowing HTML since version 3.2, with 5 being so drastically different, I dunno if I’m gonna like making the shift. I will, but the kid in me is gonna miss the old ways. *sniffle*
Thanks for posting this tutorial. It definitely has me scratching my head and wondering when to dive into coding using HTML5. But, in the end, isn’t this a moot point until the HTML5 specs are approved and added to future releases of the common modern browsers?
I’m just thinking out loud whether this has current practical applications or not. Still a very interesting read.
Nice work, only issue is when uses have JS disabled, but that accounts for very few.
Another consideration would be to use Chrome Frame to get HTML5 support.
(Plus that will solve issues with canvas and HTML A/V)
One very important reason not to rely on this script is that it won’t work for print styles. So unless you’re actually making a web app where printing is not relevant, I’d say it’s a better idea to just go with pseudo-html5 (using class=”article”, class=”nav” etc.)
Seriously, why even bother with coding HTML 5 pages when it isn’t supported across all major browsers without a hack? It’s ridiculous. The markup here isn’t THAT much more readable and workable – what’s the difference? If you’re a solid HTML/CSS coder who cares? You should know what you’re doing whether it’s called a div block, a header block or __insert random naming scheme__.
Most good devs. will tidy up their code with one of these:
I hate these articles that push for CSS3 and HTML 5 when clearl it isn’t ready yet. Like it or not, IE is a browser that is in use. IE8 is pretty darn good too despite not fully supporting HTML 5 and CSS3 which neither are fully spec’d out and in use anyhow.
Stupid article. Lets create more work by having to rely on yet another javascript just to use this markup…. pointless. Do you think your clients can tell or give a crap? Answer that one.
^^…I don’t understand your anger…nobody forces you to use this future technology nor to read articles about it, if you like you do your websites in html 4.01 or xhtml 1.x, no problem…nobody cares…
but maybe there are people who like their job (ie. creating websites) and want to be on the edge of technology, maybe just to keep up with the new stuff that comes up in the dev-scene…
your “problems” could also be seen the other way around…does your clients care if you use html 5 if the site looks nice in every major browser…they regularly don’t really care about the “what if js is disabled”-question because they don’t even know what javascript is^^…
I’m not doing sites in html 5 for my clients but I’m playing around with it on my own site, just because I’m interested in the progress we have in the internet, so I like these articles and I really can’t understand why somebody would “HATE these articles” (to cite you)…this emotion seems far too strong for some text on some webpage…you maybe have to think about your real problems^^, maybe get a new job where you don’t have to be interested in future technologies…how about gravedigger? =P
And about IE…when it comes to this piece of bad coding (in all versions) I could react like you do on this article but I don’t have to because I just don’t give a f*** about it, it’s not worth it because nothing will change, IE will stay a piece of shit (maybe they change to webkit? =D) until they trash the Trident crap…but someone who seems to really like IE…I don’t know^^…you should maybe go and see a doctor =P
have a nice day!
Any technique that relies on javascript for core site functionality like layout and tag recognition unfortunately goes against just about everything written about accessibility and web standards.
we don’t need to wait anymore, let’s start!
Nice article
goood one
And what about print stylesheets ? You can’t use javascript in this case.
Forget it. I’m tired
Yes, you are right: You can’t fully use print stylesheets with this technique: Styling any of the HTML5 elements for print will miserably fail in ALL current Internet Explorer versions.
I just encountered this problem on a customer’s website and had to replace the HTML5 elements with DIVs again …
thanks for a great tutorial.
By using above technique we can style HTML 5 elements but can we use canvas and also audio and video tag functionality?
I would like to know about that as well… :s
As of the new year (2010), it’s my resolution to start coding in HTML 5 (with html5shim). We have to move forward. I just think HTML 5 will come earlier than expected. Great article Jeff!
Well done! nice idea with javascript. Now I can start use html5
is it not compatible with ie6?
How about css3?
I believe css is dependant on browser interpretation… si any css markup that is used would depend on the browser’s interpreter… again, development is at the mercy of the endless browser wars…
A similar concern I have is with this technique being dependent on JavaScript. Usually I have more than one thing going on in the page that uses JavaScript – and occasionally JavaScript breaks. Whether it’s a 404 to a hosted jquery library, updated code that causes something else to fail – you know how it can go when a project builds on itself. I just had this happen on a site and wondered why other things in the page stopped working like they should. It had nothing to do with the code for that JavaScript-dependent feature, at least not directly.
So, bear in mind that if one thing fails, it most likely will have an impact on other things in your design!
FYI: The charset meta tag is in the wrong place, should be below the opening head tag.
hey
thanks for the tutorial
i tried javascript bt it didnt work
i m still facing the same prob and not able to c my site in IE
i main prob if footer and my site its in center in IE
it works perfactly in Firefox and other browsers.
please have a look at mi site and let me know what i can do to make it work in all browsers?
http://hencyparmar.byethost8.com/
hencyp@gmail.com
thanks you very much
hency
Thanks for that, Helpful article.
- this element needs children, how is it more useful (or correct) to have to go:
nav item
nav item
instead of:
nav item
nav item
an no, going:
nav item
nav item
is inherintly wrong because there’s no structure to the navigation; imagine a table of content in a book that was just a jumbled mess of words, resembling a sentence but with no implicit structure.
*** Repost because your form ate my tags…. ***
——–
<nav> – this element needs children, how is it more useful (or correct) to have to go:
<nav>
<ul>
<li>nav item</li>
<li>nav item</li>
</ul>
</nav>
instead of:
<ul id=”nav”>
<li>nav item</li>
<li>nav item</li>
</ul>
an no, going:
<nav>
<a>nav item</a>
<a>nav item</a>
</nav>
is inherintly wrong because there’s no structure to the navigation; imagine a table of content in a book that was just a jumbled mess of words, resembling a sentence but with no implicit structure.