Monday, November 1st, 2010

html5 Elements with non javascript fallback

When it comes to html5 and css3 I am as keen as the next developer but with html5 there is one thing that’s been holding me back…

Internet Explorer. Why? The problem is whilst Safari, Firefox, Opera and Chrome will allow you to style any element on the page and thus use the new html5 elements in your mark up such as <header>, <nav> and <section> Internet Explorer cannot naturally style these elements (hopefully to change with the release of ie9).

Remy Sharp has produced a html5 shim using js which works great. Basically it will create the html5 elements on the page allowing you to style them using your CSS just as you would with any other browser.

So what’s the problem? Well in an ideal world we do not want to rely on js for presentation, if a user has Internet Explorer <9 and javascript disabled then the page won’t render correctly.

I figured we could provide a fallback with conditional elements in the html as below:

<!--[if lt IE 9]>
<div id="header">

<!--[if !lt IE 9]>

This is a little messy really.. As a rule of thumb ‘If it can be done server side, it should be done server side‘ which means php to me.

What I wanted to do was;

  1. Detect the browser.
  2. If IE8 or less – find and replace html elements for example <header> becomes <div id="header"> (this would leave us with an element we can style).

I’m a html, css, jQuery man and don’t know much php or if my ideal is even possible.

But. One way to accomplish this would be:

<?php if (ereg('MSIE 6'|'MSIE 7'|'MSIE 8',$_SERVER['HTTP_USER_AGENT'])){ echo ('<div id="header">'); } else { echo ('<header>'); } ?>

Which says if you are Internet Explorer 6, 7 or 8 then do this: <div id="header"> if you’re anything else then do this: <header> we’d then write our content inside the element as normal and close as below:

<?php if (ereg('MSIE 6'|'MSIE 7'|'MSIE  8',$_SERVER['HTTP_USER_AGENT'])){ echo ('</div>'); }  else { echo ('</header>'); } ?>

Now the html output will be nice and clean. If you view the source in ie(6/7/8) you’ll see: <div id="header"> and in anything else: <header> no one will be any the wiser that you even used conditional elements (as everything happens server side before the page is rendered) and better still your page will render correctly cross browser even with javascript disabled.

The exact same process can be repeated for the other html5 elements such as <nav>, <section>, <aside> and <footer>.

All that’s left to do is target both selectors in your CSS for example:

header, #header { /*your styles here*/ }
nav, #nav { /*your styles here*/ }
section, .section { /*your styles here*/ }

Lastly don’t forget, that for now, even in modern browsers your html5 elements will have no default styles applied (as technically they don’t exist) so these will need to be created (and bear in mind that browsers may apply default styles to these in the near future so should apply a reset too) example:

header, nav, section, article, aside, footer {display:block; margin:0; padding:0;}

I’ve tested this method and from what I can tell it seems to work nicely, it means extra markup but at least it wouldn’t be seen client side.

Although I am yet to use this on any production sites I no doubt will in the near future, in the meantime I’d love to hear your thoughts or any improvements you can suggest.

2 Responses to “html5 Elements with non javascript fallback”

  1. Hey Andy, that’s quite a novel idea! I like it. Personally I take it for a given that JavaScript is enabled but I really should find some statistics to base my decisions on :) You should probably store the ereg() result so you can do <?php if ($nojs)… or something – faster and cleaner.

  2. Andy Kleeman says:

    Thanks for your thoughts Dave! A php developer I work with said the same and had some other suggestions also so I will try and re-work this at some point..

Leave a Reply