I’m learning about HTML5 at the moment, and my current homework assignment is to retrofit a page in such a way that it uses valid HTML5 but also works in IE6:
Make it validate as HTML5
Make sure you honor the semantics of HTML5 as well
Make sure that whatever you use would also work in IE6 and up
Sounds fine in theory, but that last one’s actually a bit tricky, because IE6 and IE7 don’t know about HTML5 elements.
HTML5 + IE6 + IE7 =
So if you do something like this:
[file lang="html" link="on"]code-snippets/ie-friendly-html5-1.txt[/file]
then IE thinks you mean
[file lang="html" link="on"]code-snippets/ie-friendly-html5-2.txt[/file]
which is totally not what you mean.. and your lovely styled HTML5 header will now collapse because it’s basically empty.
Known workarounds: CSS or JavaScript
There are workarounds, but to be honest, I’m not about to put my fellow developers through that kind of CSS hell to maintain a project that I’ve built, and the popular JavaScript solution is not appealing to me because I don’t like to rely on something as easy to disable as JavaScript is.
There’s also Chrome Frame, which is currently still in beta, and relies on users having adequate permissions, or the technical know-how to install it.
A PHP workaround
So I got my hands dirty with a bit of PHP to come up with something that, if not immediately usable on a busy high-traffic site, is at least going to let me do my homework with the minimum of fuss:
A function
[file lang="php" link="on"]code-snippets/pseudo_html5.inc.php.txt[/file]
An implementation
[file lang="php" link="on"]code-snippets/pseudo_html5_buffer.txt[/file]
How it works
This is pretty straightforward, and it would have to be, because I’m not a PHP-coder. Tracking down some appropriate Regex took a while and it’s possible that there is a cleaner solution out there, but it seems robust as-is.
- There is an array of HTML5 elements, and the HTML4 elements they should map to.
- There is a dash of Regex to find the HTML5 tags that need to be replaced.
- When the page is served, the page HTML is rendered into a buffer.
- We then loop through our array of HTML5 tags and replace any matches in the buffered HTML.
- Then we empty the buffer and output the updated HTML.
Only for IE6-7
To prevent a redundant function call by all of our HTML5-ready visitors.
- We test whether the page is being viewed in IE6 or IE7 by checking the user-agent string
- If the browser is IE6 or IE7, we run the function. If it’s not, we don’t.
Caveats
Did I mention that I’m not a PHP-coder? I’m sure this could be done better by someone who is, but, regardless, it works as a proof-of-concept.
Some things to be wary of with this approach:
- You certainly wouldn’t want the overhead of running the replacement every time the page was viewed.
My thoughts are that this process would be triggered by a user viewing the page – if the page was already cached, the cached version would be used. If not the tag rewriting would occur and then the page would be cached. Or maybe a cron job could be added to automate this dual-browser caching. - The user agent string can easily be changed in many popular browsers. My personal feeling is that this is most likely something that only a power user (or developer) would do. Regardless, the worst possible outcome for these users is that they will experience well structured pseudo HTML5 instead of fully semantic HTML5.
Feel free to flame me in the comments with any other downsides that I’ve missed
HTML/CSS Syntax
To overcome browser differences in the stylability of HTML5 elements, I’ve used CSS class names which mirror the HTML5 tag names.
While this makes the markup a little more bulky, it means that CSS can be authored once and applied to all browsers, making it easier to maintain.
It also has the advantage that the class names are visible to and usable by all developers working on a project, not just those focussing on IE compatibility.
And finally, it is a ‘means to an end’, the ‘end’ being the improved document semantics available in browsers which support HTML5, and a graceful fallback in those that don’t.
HTML5
[file lang="html" link="on"]code-snippets/ie-friendly-html5-3.txt[/file]
Pseudo HTML5
[file lang="html" link="on"]code-snippets/ie-friendly-html5-4.txt[/file]
Shared CSS
[file lang="css" link="on"]code-snippets/ie-friendly-html5-5.txt[/file]
Validation
Because div and span elements still exist in HTML5, both the ‘real’ HTML5 and the ‘pseudo’ HTML5 will validate as HTML5.
A demo
If you made it down this far, it’s only fair that you should see a demo of this in action.
Cheers.