HTML5 Part 4: Using HTML5 while retaining support for older browsers

So far this week, we’ve discussed lots of cool new functionality in HTML5, including the new semantic elements, the canvas tag for drawing, and the audio and video support.  You may think that this stuff is really cool, but you can’t possibly adopt HTML5 when many of your users don’t have HTML5-compatible browsers yet.  Not to mention that the browsers that do support HTML5 support different pieces of it; not all of the new HTML5 functionality is supported in all browsers and various features may be implemented differently. 

Never fear!  There is actually a way to target the new features and functionality without breaking your site for users with older browsers.  You can use polyfills

What is a polyfill?  According to Paul Irish, a polyfill is “a shim that mimics a future API, providing fallback functionality to older browsers”.  A polyfill fills in the gaps in older browsers that don’t support the HTML5 functionality in your site.  Learning to use polyfills will allow you as a developer to use HTML5 today without leaving behind users of older browsers. 

One way to get polyfill support is the JavaScript library Modernizr (but there are many polyfills available).  Modernizr adds feature detection capability so you can check specifically for whether a browser supports (for example) the canvas element and provide a backup option if it doesn’t. 

Let’s walk through an example.  Remember the code sample that I used when introducing semantic elements and page layout?  Here it is again:

 <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Title</title>
    <link href="css/html5reset.css" rel="stylesheet" />
    <link href="css/style.css" rel="stylesheet" />
</head>
<body>
    <header>
        <hgroup>
            <h1>Header in h1</h1>
            <h2>Subheader in h2</h2>
        </hgroup>
    </header>
    <nav>
        <ul>
            <li><a href="#">Menu Option 1</a></li>
            <li><a href="#">Menu Option 2</a></li>
            <li><a href="#">Menu Option 3</a></li>
        </ul>
    </nav>
    <section>
        <article>
            <header>
                <h1>Article #1</h1>
            </header>
            <section>
                This is the first article.  This is <mark>highlighted</mark>.
            </section>
        </article>
        <article>
            <header>
                <h1>Article #2</h1>
            </header>
            <section>
                This is the second article.  These articles could be blog posts, etc.  
            </section>
        </article>
    </section>
    <aside>
        <section>
            <h1>Links</h1>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
            </ul>
        </section>
        <figure>
            <img width="85" height="85" 
                src="https://www.windowsdevbootcamp.com/Images/JennMar.jpg" 
                alt="Jennifer Marsman" />
            <figcaption>Jennifer Marsman</figcaption>
        </figure>
    </aside>
    <footer>Footer - Copyright 2011</footer>
</body>
</html>

This code contains a number of new HTML5 elements that aren’t supported in older browsers.  Remember that in Internet Explorer 9, it looked like this:

PageLayout

We can use the Internet Explorer developer tools to see what this would look like in older versions of IE.  In Internet Explorer, press F12 to access the developer tools. 

image

Note that the Browser Mode (in the grey menu bar across the top) is currently set to IE9.  Click on the Browser Mode, and from the resulting dropdown menu, select “Internet Explorer 8” (which does not have HTML5 support). 

image

What happens to my webpage after I make this change and switch to a non-HTML5-compatible browser?  See for yourself:

image

Much wailing and gnashing of teeth!  It’s a mess.  There’s no chance of using HTML5 now, right? 

It’s not actually that bad.  The reason that this doesn’t work is that IE8 doesn’t recognize the new HTML5 elements that I’m using, so it doesn’t add them to the DOM, so you can’t style them using CSS. 

However, just adding a reference to Modernizr (without making any other code changes!) will brute-force these elements into the DOM.  Download it from here and add a reference in the <head> section like so:

 <head>
    <meta charset="utf-8" />
    <title>Title</title>
    <link href="css/html5reset.css" rel="stylesheet" />
    <link href="css/style.css" rel="stylesheet" />
    <script src="script/jquery-1.6.2.min.js" type="text/javascript"></script>
    <script src="script/modernizr-2.0.6.js" type="text/javascript"></script>
</head>

I added two script references, one to jQuery and one to Modernizr.  I don’t actually need the jQuery reference at this point, but we will need it for the next script, so I’m adding it now. 

Just this simple change now gets my site to this state in Internet Explorer 8: 

image

It’s not perfect, but that is pretty close to the original version that we see in Internet Explorer 9.  Modernizr added these new HTML5 elements that IE8 didn’t understand into the DOM, and since they were in the DOM, we could style them using CSS. 

But Modernizr does more than that!  Notice that one of the differences between our IE8 and IE9 versions of the webpage is that the IE9 version has nice rounded corners on the two articles and the figure, and the IE8 version doesn’t.  We can also use Modernizr to fix this. 

     <script type="text/javascript">
        if (!Modernizr.borderradius) {
            $.getScript("script/jquery.corner.js", function() {
                $("article").corner();
                $("figure").corner();
            });
        }
    </script>

In this script, we’re checking the Modernizr object to see if there is support for “borderradius” (a CSS3 feature).  If not, I use a jQuery script called jquery.corner.js (which is available for download here and requires that extra reference to jQuery which I made earlier).  Then I simply call the corner method from that script on my articles and figures to give them rounded corners. 

OR, you can do this a slightly different way.  Modernizr has an optional (not included) conditional resource loader called Modernizr.load(), based on Yepnope.js.  This allows you to load only the polyfilling scripts that your users need, and it loads scripts asynchronously and in parallel which can sometimes offer a performance boost.  To get Modernizr.load, you have to include it in a custom build of Modernizr which you have to create here; it is not included in the Development version.  With Modernizr.load, we can write a script like this:

     <script type="text/javascript">
        Modernizr.load({
            test: Modernizr.borderradius,
            nope: 'script/jquery.corner.js',
            callback: function () {
                $('article').corner();
                $('figure').corner();
            }
        });
    </script>

In short, this implements the same functionality as our previous script.  Modernizr.load first tests the Boolean property “Modernizr.borderradius” to see if it is supported.  Then, nope defines the resources to load if test is false.  Since IE8 doesn’t support the CSS3 property “borderradius”, it will load the jquery.corner.js script.  Finally, the callback specifies a function to run whenever the script is done loading, so we will call the “corner” method on my articles and figures as we did before.  There is a brief tutorial on Modernizr.load here if you want to dive deeper. 

Now, by using either of those scripts, our Internet Explorer 8 version (which doesn’t support HTML5) looks like this:

image

Therefore, using polyfills and tools like Modernizr allows you to utilize new HTML5 functionality and still provide a good experience on older browsers as well.  For more information, check out https://www.diveintohtml5.org/detect.html which describes in detail how Modernizr detects HTML5 features. 

Stay tuned for my last post tomorrow, when I will provide some resources, websites, and tools to continue learning about HTML5

 

Other blog posts in this series:

  1. HTML5 Part 1: Semantic Markup and Page Layout
  2. HTML5 Part 2: Canvas
  3. HTML5 Part 3: Audio and Video
  4. HTML5 Part 4: Using HTML5 while retaining support for older browsers
  5. HTML5 Part 5: Resources, Websites, and Tools