Want to use modern web features but need to support older browsers? Polyfills might be the solution. Jason Johnston fills in the essential details
Fortunately there is a middle ground that has become increasingly popular: polyfills. This term refers to a specific type of shim that implements a standard web feature or API in browsers that lack support natively.
Polyfills are unobtrusive

Polyfills are temporary
For this automatic obsolescence to work, you must make sure that you are including the polyfill only in those browsers that need it. We will be returning to this later, in the section of the article that deals with conditional loading. It’s natural to think of polyfills as tools for improving the experience in outdated browsers, since that’s where they do their work. But it’s better to think of them as tools for improving the experience in modern browsers, while old ones are secondary.
Why is that? Well, since polyfills facilitate writing plain standard code as the baseline, the modern browsers that support it will benefit from drastically smaller file sizes, faster rendering and well-integrated native implementations. The old browsers would be downloading and running extra shim code regardless of whether you chose another library or shim, but a polyfill prevents the capable browsers from having to do the same.
In short, polyfills enable you to stop hurting your users who come to your site in modern browsers, without leaving the others behind.
Polyfills aren’t just for old browsers

A good example is the CSS.supports polyfill, which implements the CSS.supports JavaScript API from the CSS3 Conditional Rules Module working draft. Although no browsers currently shipping implement this API, it is expected to be supported in future, so this polyfill lets developers start using the API today. In theory, once browsers start shipping with a native implementation, that will take over seamlessly and the polyfill will stop being used.
But beware: using features based on an unfinished specification is inherently risky! This is the case whether you choose to polyfill them or not – if the spec changes, your code won’t work when the final native implementation comes along. We’ve already seen this happen, for example, with the CSS3 Flexible Box Layout module, which has changed drastically so that sites using the old draft syntax along with the popular Flexie polyfill will not work in browsers that implement the final syntax without code changes. A good rule of thumb: unless you are willing to diligently update your site’s code along with spec changes, you should avoid using draft features.
How do you use a polyfill?
Script includes

For example, Lea Verou’s popular -prefix-free polyfill enables support for several un-prefixed CSS properties in browsers that only support the vendor-prefixed versions. To use it, you need todownload the prefixfree.min.js file and include it in your page immediately after your style sheets:
-
<script src=“/path/to/prefixfree.min.js”></script>
-
.myClass {
-
box–shadow: 0 2px 5px rgba(0, 0, 0, .5);
-
}
-
.myClass {
-
–moz–box–shadow: 0 2px 5px rgba(0, 0, 0, .5);
-
}
HTC behaviors
As an example, the CSS3 PIE polyfill (disclaimer: I created it) uses an HTC behavior to render some of the most common CSS3 box decoration properties in IE6 through 9. It is applied by adding the behavior property to your CSS3-styled elements:
-
.myClass {
-
border–radius: 8px;
-
box–shadow: #666 0px 2px 3px;
-
behavior: url(/path/to/PIE.htc);
-
}
An HTC behavior has some distinct advantages over a normal script file: it can execute before the full page is loaded, it reacts automatically to dynamic addition and removal of page elements, and since non-IE browsers ignore the unknown behavior CSS property, it provides conditional loading by its very nature.
However there are some gotchas: the HTC file must be in the same domain as the page using it, the server must send it using the correct Content- Type HTTP header, and the behaviorproperty resolves relative URLs based on the HTML page rather than the CSS file location. These can make using the polyfill trickier, so keep them in mind.

Conditionally loading polyfills
Conditional comments
-
<!–[if lt IE 9]>
-
<script src=“path/to/html5shiv.js”></script>
-
<![endif]–>
Additional JavaScript
-
<script>
-
if (!window.JSON) {
-
document.write(‘<script src=”path/to/json2.js”>
-
</script>’);
-
}
-
</script>
Asynchronous loading
-
<script>
-
if (!window.JSON) {
-
(function(d, t) {
-
var g = d.createElement(t), s =
-
d.getElementsByTagName(t)[0];
-
g.src = ‘path/to/json2.js’;
-
s.parentNode.insertBefore(g, s);
-
})(document, ‘script’);
-
}
-
</script>
Modernizr.load
For example, if you need to store persistent client-side data, HTML5’s localStorage API is a logical choice. Fortunately there are a number of polyfills that emulate it in older browsers. First, go to www.modernizr.com/download and select the localStorage feature test and Modernizr.load. Generate and download the result, place it in your site directory, and include it in your page:
-
<script src=“/path/to/modernizr.custom.12345.js”></script>
Finally, let’s use the Modernizr.load method to test for the presence of native localStorage and load the storage polyfill if it is not supported. We’ll also make use of Modernizr.load’s ‘complete’ callback to add some default data to the localStorage once it’s available and/or polyfilled:
-
<script>
-
Modernizr.load({
-
test: Modernizr.localstorage,
-
nope: ‘/path/to/storage.min.js’,
-
complete: function() {
-
if (!localStorage.getItem(‘firstRunTime’)) {
-
localStorage.setItem(‘firstRunTime’, ” + new Date());
-
}
-
}
-
});
-
</script>

How do polyfills work?
1. Create new global JavaScript objects
For APIs that are exposed in global objects, like window.JSON or window.localStorage.
2. Add properties/methods to object prototypes
For APIs that are additions to existing objects, like Array.prototype.forEach().
3. Execute plug-ins
For things that can’t be emulated with other built-in browser features, such as HTML5 <video>.
4. Parse and rewrite CSS
To interpret CSS selectors or properties that the browser doesn’t recognise for itself.
5. Query and modify the DOM
To change the end result seen by the user.
Also, nearly all polyfills rely on JavaScript to work their magic, so be aware that users with JavaScript disabled will not benefit.
Testing with polyfills
As always, test the page using the version of the browser that your visitors will be using. If you can, get this info from your site – the best stats are local!

If you are unable to maintain virtual machines, you can use an online testing tool. Make sure that it is an interactive tool, not one that simply takes screenshots, because those often don’t capture things at the right time and don’t give you any sense of performance. I recommendBrowserStack: it isn’t free, but it is the most accurate such tool I’ve seen.

Thanx….. that was a great article over there….. will make a link to it later.
Thanx….. that was a great article over there….. will make a link to it later.
Amazing effort, amazing post! Thanks so much for this great stuff. A good one on polyfills that seems to go well with your post is right here:
polyfills tutorial