IE-friendly HTML5

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.

  1. There is an array of HTML5 elements, and the HTML4 elements they should map to.
  2. There is a dash of Regex to find the HTML5 tags that need to be replaced.
  3. When the page is served, the page HTML is rendered into a buffer.
  4. We then loop through our array of HTML5 tags and replace any matches in the buffered HTML.
  5. 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.

  1. We test whether the page is being viewed in IE6 or IE7 by checking the user-agent string
  2. 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:

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

Ten or Twenty improvements for Twenty Ten: Part 1

Do The Right Thing came back-from-the-dead yesterday with the help of WordPress. Originally the site was built in Blogger, but when Blogger dropped support for FTP publishing, the site was replaced by a holding page pending some spare time to do something about it…

I’m enjoying the new default WordPress skin ‘Twenty Ten’, which replaces the questionable ‘Kubrick’ theme that used to be the default. The new skin uses the latest web technologies – HTML5 replaces HTML4, and WAI-ARIA roles have been added to add extra semantic value to the page, increasing usability in screenreaders and the like.

I’ve been been learning about HTML5 recently so it’s timely that I now have a playground for this which is outside of the constraints of paid work, and is as easy to work with as WordPress is.

In line with what I’ve been learning (and what I already know), I’ve made a few improvements to the Twenty Ten skin. I’ll document these in separate posts to keep these short and readable.

Part 1: Search widget

  1. fieldset wrapped around the form elements, to group them (a personal preference)
  2. legend added to fieldset, to act as a heading
  3. input type changed from text to search, to pick up the new formatting options available in Safari (this degrades to a type of text in other browsers)
  4. placeholder attribute added to input to display this text inside the field in Safari (this degrades to no placeholder text displayed in other browsers)

Apologies for the messy code highlighting – I’m still working on getting the beautyOfCode syntax brushes applying correctly.

HTML

[file lang="html" link="on"]code-snippets/ten-twenty-part-1-search-html.txt[/file]

PHP

[file lang="php" link="on"]code-snippets/ten-twenty-part-1-search-php.txt[/file]