There's been a lot of commotion over the last week since the W3C announced that <a href="http://www.infoworld.com/d/developer-world/w3c-hold-html5-in-websites-041?page=0,0">HTML5 is not ready yet for deployment to websites</a>. Some really <a href="http://remy.tumblr.com/post/1261575750/hold-off-on-deploying-html5-in-websites">smart</a> <a href="http://almaer.com/blog/dont-deploy-html5-thanks-again-w3c">people</a> have weighed in on this topic and I agree with their thoughts. Last Thursday, I did a presentation on the new features of HTML5 and part of that was demonstrating how polyfills work to allow you to leverage these new features while still providing a good cross-browser experience.

<h2>What's a Polyfill?</h2>

I really love Paul Irish's definition since it sums it up perfectly:

<blockquote>polyfill: A shim that mimics a future API, providing fallback functionality to older browsers.</blockquote>

The basic premise is that most older browsers may not have all of the features of the HTML5 and CSS3 specifications and they need a helping hand to make them provide a good user experience. A great example of this are the new HTML5 semantic tags like &lt;article&gt;, &lt;section&gt;, &lt;header&gt; & &lt;nav&gt; which render fine in all major modern browsers like IE9 beta, Firefox, Chrome, Safari & Opera but lack support in popular browsers like IE6 through IE8. 

So for my demo, I decided to create a simple page that showed a blog-like layout using these new tags while ensuring that they can still render correctly in IE8. Here's the layout code I used. 

[code lang="html"]
&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;title&gt;Rey's Awesome HTML5 Blog&lt;/title&gt;
    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;
    &lt;meta name=&quot;keywords&quot; content=&quot;&quot; /&gt;
    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width; initial-scale=1.0&quot; /&gt;
     
    &lt;!-- !CSS --&gt;
    &lt;link href=&quot;css/html5reset.css&quot; rel=&quot;stylesheet&quot; /&gt;
    &lt;link href=&quot;css/style.css&quot; rel=&quot;stylesheet&quot; /&gt;
  
&lt;/head&gt;
 
&lt;body&gt;
    
	&lt;header&gt;
        &lt;h1&gt;Rey's Awesome HTML5 Blog&lt;/h1&gt;
	&lt;/header&gt;

    &lt;nav&gt;
    	&lt;ul&gt;
			&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href=&quot;#&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
    &lt;/nav&gt;
    	
	&lt;section&gt;

        &lt;header&gt;
        &lt;h1&gt;Rey's Blog Posts&lt;/h1&gt;
	    &lt;/header&gt;

        &lt;article&gt;
            &lt;header&gt;&lt;h1&gt;The In's &amp; Out's of HTML5&lt;/h1&gt;&lt;/header&gt;
		    &lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing  elit. Fusce vitae orci. &lt;/p&gt;

            &lt;footer&gt;
                October 7, 2010 - comments( 0 )
            &lt;/footer&gt;
        &lt;/article&gt;

        &lt;article&gt;
            &lt;header&gt;&lt;h1&gt;HTML5 Ate My Lunch&lt;/h1&gt;&lt;/header&gt;
		    &lt;p&gt;Fusce vitae orci. Lorem ipsum dolor sit amet, consectetuer adipiscing  elit. &lt;/p&gt;
            &lt;footer&gt;
                October 5, 2010 - comments( 3 )
            &lt;/footer&gt;
	    &lt;/article&gt;		

	&lt;/section&gt;
		
	&lt;footer&gt;
		&lt;p&gt;Copyright Rey Bango, 2010&lt;/p&gt;
	&lt;/footer&gt;

&lt;/body&gt;
 &lt;/html&gt;
[/code]

I used a <a href="http://html5doctor.com/html-5-reset-stylesheet/">HTML5 reset style sheet</a> because unfortunately, most browser don't have an internal style sheet that sets the expected behavior for specific elements. For example, you would expect an &lt;section&gt; element to be block level but due to a lack of the internal browser style sheet, it renders inline. 

Then, I added the styles I needed to get my page to look the way I wanted:

[code lang="css"]
/* Global */
body { font-size: 16px; font-family: arial,helvetica,clean,sans-serif;  }
a { color : #33CC33; } 
a:hover { text-decoration: none; }

/* Header */
header h1 { font-size: 48px; }

nav { overflow: auto; margin-bottom: 25px; }
nav li {float:left; padding-right: 5px; }

/* Main Content Area */
section { width: 500px; font-size: 12px; }
section h1 { font-size: 16px; }

article { background: #CCCC99; margin-bottom: 10px; padding: 5px; -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; }
article footer { text-align: right; margin-right:5px; } 
article h1 { font-size: 12px; }
[/code]

and when I tested it in Firefox 3.6.10, it looked exactly like I expected:

<a href="http://blog.reybango.com/wp-content/uploads/2010/10/fx-blog.png"><img src="http://blog.reybango.com/wp-content/uploads/2010/10/fx-blog-300x180.png" alt="" title="fx-blog" width="300" height="180" class="alignleft size-medium wp-image-1429" /></a>

but look what happened when I tried to bring up the page in IE8:

<a href="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-nopf.png"><img src="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-nopf-300x239.png" alt="" title="ie8-blog-nopf" width="300" height="239" class="alignleft size-medium wp-image-1434" /></a>

None of the stylings were available because IE8 doesn't recognize the new HTML5 tags. Further, in order to get IE6-8 to recognize these tags, you explicitly have to create the DOM nodes for them using JavaScript. The exact reason is unclear but it seems to be some type of parse bug. The following code needs to be in the &lt;head&gt; section of your page in order for the elements to be created and recognized by IE6-8:

[code lang="js"]
document.createElement(&quot;header&quot;);
document.createElement(&quot;nav&quot;);
document.createElement(&quot;section&quot;);
document.createElement(&quot;article&quot;);
document.createElement(&quot;footer&quot;);
[/code]

It's a little bothersome to do that but it's not a massive bit of code at least.

<h2>Enter Modernizr</h2>

The code I just listed to create your HTML5 elements is certainly useful but work has already been done to handle that for us via the awesome <a href="http://www.modernizr.com/">Modernizr JavaScript library</a>. Not only does it act as a polyfill, creating these new elements for us automatically, but it offers a ton of detection capabilities for features of both HTML5 & CSS3. This allows you to determine how you will offer fallback support when a feature isn't available.

Including Modernizr.js is incredibly easy since it's only a one line script tag like this:

[code language="lang=&quot;html"]
&lt;script src=&quot;js/modernizr-1.5.min.js&quot;&gt;&lt;/script&gt;
[/code]

As I mentioned, Modernizr is smart enough to determine when new semantic elements need to be created and will handle the dynamic creation of elements such as &lt;article&gt;, &lt;section&gt;, &lt;header&gt; & &lt;nav&gt; instead of you having to write JavaScript code to do it.

<a href="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-mod.png"><img src="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-mod-300x176.png" alt="" title="ie8-blog-mod" width="300" height="176" class="alignleft size-medium wp-image-1441" /></a>

Now you're probably looking at this screenshot and say, "Hey, you have no rounded corners!". You're right because I used the CSS3 <em>border-radius</em> property to create rounder corners for all of my &lt;article&gt; elements and IE8 doesn't support that property. The important thing, though, is that IE8 now recognizes these new elements and allowed me to style them.

<h2>But What About those Rounder Corners?</h2>

Geez, you guys are so demanding! Okay, so the cool thing is that Modernizr offers detection of key features of HTML5 *and* CSS3 and with that, we can determine if something like <em>border-radius</em> is available and if not, using a new term coined by Alex Sexton, we'll use "<strong>regressive enhancement</strong>" to provide similar capabilities for older browsers. In this case, we're going to see if border-radius is available and if not, lazyload in <a href="http://jquery.malsup.com/corner/">Mike Aslup's jQuery Corners plugin</a> to fill in the gap:

[code lang="js"]
    &lt;!-- Load jQuery --&gt;
    &lt;script src=&quot;http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    
    &lt;script type=&quot;text/javascript&quot;&gt;
        // See if border-radius is available 
        if (!Modernizr.borderradius) {

            // If not, then load in the jQuery Corners plugin and apply rounded corners to the article elements
            $.getScript(&quot;js/jquery.corner.js&quot;, function () {
                $(&quot;article&quot;).corner();
            });

        }
    &lt;/script&gt;

[/code]

Now, when the code detects that <em>border-radius</em> is not available, it will just use the Corners jQuery plugin instead and render the following in any browser that doesn't support the property:

<a href="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-mod-corners.png"><img src="http://blog.reybango.com/wp-content/uploads/2010/10/ie8-blog-mod-corners-300x176.png" alt="" title="ie8-blog-mod-corners" width="300" height="176" class="alignleft size-medium wp-image-1449" /></a>


<h2>Download the Code</h2>

I hope this post has shown you how polyfills can allow you to use HTML5 & CSS3 today. While I respect the W3C's desire to ensure that the HTML5 specification is up-to-snuff, I think it's important to realize that developers are resourceful and professional enough to create best practices that allow us to build apps with these new features right now.

I would highly recommend reviewing this <a href="http://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">VERY BIG LIST of polyfills and shims</a> which can provide much of the missing capabilities in older browsers. 

If you'd like to play with the code directly, I've packaged it up in a .zip file and you can download it here:

<a href='http://blog.reybango.com/wp-content/uploads/2010/10/polyfills.zip'>Code for HTML5 Semantic Tags using Polyfill to Degrade Gracefully (.zip)</a>


