Sunday, 25 December 2011

How to Make Internet Explorer Render HTML5 Without JavaScript

The excitement surrounding HTML5 is gathering pace, and as developers we're generally keen to embrace it. This is a good thing, it is after all "the way of the future".
For quite some time I have been looking forward to using HTML5, and with all the modern browsers out there now supporting it, at least in part if not in full, it's as good a time as any. But hold on, aren't we forgetting something here?
Of course we are, Internet Explorer (More specifically IE6/7/8).
We're all painfully aware of the headaches caused by Internet Explorer. For quite some time it has attempted to block our progress in the form of version 6 but our problems weren't over with the subsequent releases of IE7 and even IE8. Sure the browser has improved with every release but it is still some way off when compared to the other popular browsers on the market. We have the option of using HTML5 to deliver the lovely new features to FireFox,Chrome,Safari,Opera and IE9 users, but at the expense of potentially alienating those users still stuck with a legacy version of IE. But that's okay, right?
Correct! But only if you've created a website for an audience where the vast majority of them are likely to have the latest technologies or are willing (and able) if not, to make the necessary upgrade.
But it is wrong it you are developing a website for a corporate audience, with IE6/7/8 useage figures still coming in at 10-15%. It is probably not a good idea to exclude them for being slow on the uptake in terms of their browser version.

Progressive Enhancement / Graceful Degradation
For quite some time the paradigms, progressive enhancement and graceful degradation, have been around and become a cornerstone of responsible web development. At its heart, without going on too much, is adaptability. By that I mean, the ability of the website to adapt to what the browser can handle, and gracefully exclude those features beyond its scope. It makes sense that if a browser struggles with some CSS3, then provide it with something to fall back on. If it hasn't got JavaScript enabled, the website (quite reasonably) should still operate without fault, albeit with less polish and all those bells and whistles. Us developers love to enhance the user experience and JavaScript is there for us to exploit.
And this brings me to my point...

To Shiv or Not to Shiv
Thanks to Sjoerd Visscher, and the discovery that JavaScript can trick legacy browsers into rendering unknown HTML elements, and further work by John Resig and others we've had the ability to make IE6/7/8 'understand' the new HTML5 elements. Enter the HTML5 shiv.
I'm all for this kind of innovation, it's tremendous but what about those paradigms? What do we do? We're damned if we do use it (because JavaScript dependency breaks the rules) and damned if we don't because, well, that breaks the rules too. Oh dear.
So, reluctantly the responsible web developers of the world sit back, sigh and fire up their XHTML boilerplate again, and start coding their next project in safety.

There is Another Way
But can we use HTML5 yet, given the aforementioned dependency on JavaScript? This question was raised again recently at the start of a new project, and I decided that there had to be a way to deliver valid HTML5 without any JavaScript dependency.
Conditional Comments - the kind we've been using to 'filter' IE rules without cluttering up that perfect thing of beauty; our validated css files.
This snippet will break old IE:

  <h2>This is a header</h2>
  <p>This is a paragraph.</p>

However, I discovered recently that this will work:

<!--[if lt IE 9]><div><![endif]-->
    <h2>This is a header</h2>
    <p>This is a paragraph.</p>
<!--[if lt IE 9]></div><![endif]-->

And the reason is simple enough. The conditional comments drop in a div (surrogate) element wrapper. Old IE understands... old IE happy now. It doesn't care about the article element, after all, this lack of 'caring' caused the whole problem in the first place. So now we have a block element surrounding our article.
The best part is that this approach doesn't break any other browser, and it validates perfectly as HTML5. And why shouldn't it? These are merely comments to all but IE, and by targeting only those versions less than 9 we allow IE9 to go ahead and use the official HTML5 elements.
Now to make it more useable I added a class to the surrogate div element and named it semantically as "article":

<!--[if lt IE 9]><div class="article"><![endif]-->
    <h2>This is a header</h2>
    <p>This is a paragraph.</p>
<!--[if lt IE 9]></div><![endif]-->

Using the established method I include an IE-only stylesheet: (Line wraps marked » —Ed.)

<!--[if lt IE 9]><link rel="stylesheet" type="text »
/css" href="../styles/ie_styles.css"/><![endif]-->

Which contains the necessary styling (this is just a snippet):
.article {
margin: 10px;
padding: 10px;
width: 760px;

By keeping the class name the same as the element it is supporting it is quite easy to maintain. In the real world additional classes would be needed and these can be added to support this as normal:

<!--[if lt IE 9]><div class="article main-stories"><![endif]-->
  <article class="main-stories">
    <h2>This is a header</h2>
    <p>This is a paragraph.</p>
<!--[if lt IE 9]></div><![endif]-->

In this example I chose a div as surrogate because it is inherently recognised as a block element and so too is article. If the HTML5 element was an inline element then I would probably go for span as the surrogate.
Okay let's summarize this approach:
The positives:
  • It is simple to implement, and familiar.
  • It still validates as HTML5 with no problems.
  • It doesn't rely on JavaScript.
The negatives:
  • It is a bit messy to look at.
  • It adds quite a lot of bytes to the average webpage.
  • It possibly makes the page more difficult to maintain.
With all this said and done I have yet to try it out for real. I intend to give it a go on upcoming projects and try it for size.
At this stage I see no reason why it isn't viable.
I have provided a sample page using this technique. When viewed in IE6/7/8 or any modern browser, the same layout should be rendered. Note that I've embedded all the styles into the same page for simplicity rather than providing individual CSS files.
A name for this technique? How about 'HTML5 Shivless' or 'HTML5 Shimple'.
Happy coding.