Polyfilling the HTML5 Gaps with Addy Osmani

A little about me

Why Do Polyfills Matter?

First do it. Then do it right. Then do it better.

WebGL in IE7, 8 & 9 using JebGL (Video)

<canvas> in IE7 & 8 with FlashCanvas (Demo)

WebSocket API support with instant fallbacks to long polling using socket.io (Demo)

CSS3Pie - A polyfill for CSS3 decoration features

CSS3 border-radius,box-shadow and gradients in IE7

CSS3 patterns gallery for modern browsers (Demo)

Which we can polyfill for IE9 (Demo)

getUserMedia() (Canary/Opera.next) (Demo)

getUserMedia() shim (cross-browser) (Demo)

This is only the tip of the iceberg

Imagine if we could polyfill things like..

Features & Support

All of these features are now possible..

but support is fragmented

HTML5 & CSS3 Readiness (View)

Can I Use? (View)

oldIE: Internet Explorer 6, 7 & 8. aka, the three browsers often getting the low-res experience.
Paul Irish

Our biggest issue - browser support

New features will never be available in oldIE.

Unless you're using something like
Chrome Frame

Google Chrome Frame

Hold on! Support isn't just an IE issue!

Bleeding-edge features aren't available in all modern browsers at the same time.

Can we use modern features now? Let's wait...or

Use Polyfills & Shims

Polyfills are a type of shim that retrofit legacy browsers with modern HTML5/CSS3 features
Remy Sharp
Shims refer to any code that intercepts API calls and provides a layer of abstraction
Paul Irish

What can they do?

Polyfills help us use today's modern features in yesterday's browsers

What polyfills are widely used today?

HTML5 Please - Use features responsibly (View)

HTML5 Please API (View)

HTML5 Please Widget - Is your browser compatible?

Modernizr - feature detection made simple

Modernizr feature-detection tests

We'll look at more Modernizr feature detection tests later.


Modernizr also supports custom feature detection plug-ins

WebAudio API

        !!(window.webkitAudioContext || window.AudioContext));

Track API

        typeof document.createElement('video').addTextTrack 
        === 'function');

Include HTML5Shim & we can also enable styling and using semantic HTML5 elements in oldIE

More issues

The solution

<!DOCTYPE html>
<style>section { border:1px solid red; display:block}</style>
    <p>Hello FITC!</p>

We can now style a HTML5 element in IE6 and above

So, HTML5Shim..

Issues & Solutions

It's important to remember..

Take the 'hardboiled' approach

'Hardboiled Web Design' by Andy Clarke

It's okay for users to get different experiences

Lo-res - users are still delivered content. Default stylesheet used instead.

Be a champion of performance

Optimize to make best use of the capabilities a user's browser supports

Only load polyfills if they're absolutely needed

There are some great script loaders that can help with conditional loading

yepnope.js - an asynchronous conditional resource loader

Example: conditionally load a geolocation polyfill and stylesheet

  test: Modernizr.geolocation,
  yep: 'regular-styles.css',
  nope: ['modified-styles.css', 'geolocation-polyfill.js'],
  callback: function (url, result, key) {
    if (url === 'modified-styles.css') {
      alert("woohoo! it's loaded");

Modernizr includes yepnope.js in special builds

Supports similarly loading up a geolocation polyfill depending on support

  test: Modernizr.geolocation,
  yep : 'geo.js',
  nope: 'geo-polyfill.js'


Example: conditionally load a JSON polyfill if it isn't natively supported

   if (typeof JSON == "undefined") return "json2.js";

An alternative:

$LAB.script(typeof JSON == "undefined" ? "json2.js" : false).wait()

YeahNo.js - a yepnope API wrapper around LabJS

Example: conditionally load a geolocation polyfill and stylesheet

  test: Modernizr.geolocation,
  yep: 'regular-styles.css',
  nope: ['modified-styles.css', 'geolocation-polyfill.js'],
  callback: function (url, result, key) {
    if (url === 'modified-styles.css') {
      alert('The Styles loaded!');

Writing Polyfills

Writing Polyfills

Why should you give writing polyfills a go?

Test what features your current browser supports (View)

Does Browser-x natively support the feature? Browser.next?

Specifications - What does the API look Like? Check standards groups like the W3C for specs

Quirks - What quirks do older browser implementations suffer from? QuirksMode.org

You can't detect 'HTML5 Support', but you can detect support for individual features
Mark Pilgrim

Feature detection has some friends

There are some useful tips to keep in mind


Detecting finalized and unfinalized features. Test if:

  1. Property of the feature exists on a global object (window or navigator)
  2. Property of the feature exists on a specific element
  3. Method of the feature exists on a specific element where the value it returns can be tested
  4. Property of the feature can be set and its value retained

1. Property exists on a global object

Testing for geolocation support

function isGeolocationSupported(){
  return !!navigator.geolocation;

and with Modernizr it's as simple as..

  // supported
  // not supported

2. Property of the feature exists on a specific element

Testing for <canvas> support

function isCanvasSupported(){
  return !!document.createElement('canvas').getContext;

and with Modernizr its..

  // supported
  // not supported

3. Method of the feature exists on a specific element where the value it returns can be tested

Testing for <audio> support

function isAudioSupported(){
  return !!document.createElement('audio').canPlayType;

and with Modernizr its..

  // supported
  // not supported

But we can take this further

Testing for <audio> format support

  var audio = document.createElement('audio');
    //supports MP3 audio
    audio.src = 'music.mp3';
  else if(audio.canPlayType('video/ogg; codecs="theora"')=='probably'){
    //supports Ogg/Vorbis audio
    audio.src = 'music.ogg';
  //load a flash fallback

and with Modernizr its..

  var audio = new Audio();

  //If Ogg is supported, load 'music.ogg'
  //Otherwise the MP3 or M4A fallback depending
  //on browser support
  audio.src = Modernizr.audio.ogg ? 'music.ogg' :
              Modernizr.audio.mp3 ? 'music.mp3' :
  //use a flash fallback

4. Property of the feature can be set and its value retained

Testing for <input type="color"> support

function isColorPickerSupported(){
  var input = document.createElement('input');
  return input.type !== 'text';

and with Modernizr its..

  // supported
  // not supported

Vendor prefixes

Allow vendors to implement experimental features before they've been finalized

// From css3please.com:
.box_transition {
  -webkit-transition: all 0.3s ease-out;  /* Saf3.2+, Chrome */
     -moz-transition: all 0.3s ease-out;  /* FF4+ */
      -ms-transition: all 0.3s ease-out;  /* IE10? */
       -o-transition: all 0.3s ease-out;  /* Opera 10.5+ */
          transition: all 0.3s ease-out;  /*fast-forward compatible*/

Edge-features occasionally need to be tested prepending a vendor prefix to the feature name.

CSS3 Please - The Cross-Browser Rule Generator (View)

Getting the vendor prefix

function getPrefix(prop){
  var prefixes = ['Moz','Khtml','Webkit','O','ms'],
      elem     = document.createElement('div'),
      upper    = prop.charAt(0).toUpperCase() + prop.slice(1);

  if (prop in elem.style)
    return prop;
  for (var len = prefixes.length; len--; ){
    if ((prefixes[len] + upper)  in elem.style)
      return (prefixes[len] + upper);
  return false;


Getting the vendor prefix with Modernizr


Watch out! Not everything can be detected (View)


  • Benchmark performance of the complete polyfill
  • Are there other scripts loading on the page?
  • Polyfills relying on other polyfills?

Break your polyfill into smaller parts. Can those be tested or optimized further?

Is the polyfill visibly slow in some browsers? Use vs. lose

Benchmark performance with jsPerf.com (View)

Case study: forEach() (ES5)

The Future

Polyfills will probably still exist in the future.

Will they be around forever?

As browser vendors implement new specs and features, the need for specific polyfills will decrease.

Firefox nightlies

Chromium (Stable, Beta, Canary builds)


Internet Explorer Preview


What did we learn today?

That's a wrap!

For more on me:


Big thanks to @paul_irish, @mathias, @peol, @rem and others for their previous work in this area and technical reviews.