Modernizr: Detect HTML5 Features and Provide Fallbacks

Modernizr logo

Modernizr is a JavaScript library that detects which HTML5 and CSS3 features your visitor’s browser supports. In detecting feature support, it allows developers to test for some of the new technologies and then provide fallbacks for browsers that do not support them. This is called feature detection and is much more efficient than browser sniffing.

Modernizr is very useful for detecting CSS3 support, but this article will focus on HTML5. The principles are essentially the same, though.

It’s important to note that Modernizr doesn’t “fill in the gaps” (i.e., polyfill) for you. It only detects whether something is supported. But you can use Modernizr as part of the polyfilling process.

Versions of IE8 and below do not recognise new-in-HTML5 elements by default, so you have to fix this with some JavaScript. You could possibly create each of these yourself with the below code, or you might use the HTML5 Shiv by @rem, which includes all the new elements.

Modernizr does all this for you, so you don’t need include the Shiv.

Getting Started

First, you need an HTML document:

You can see in the code above that you need a modernizr.js file. You have to build and download this yourself by choosing the features you want to detect. Do this by choosing the ‘Production’ option in Figure 1 and then ticking the necessary options in Figure 2. This helps keep the file size down by not detecting everything Modernizr is capable of. There is a development version (see Figure 1) that you can link to whilst developing your site, but before you put the site live, you should build the production file you need.

Modernizr download options

Figure 1: Modernizr download options
Modernizr build options

Figure 2: Modernizr configuration & build options

Also notice the second line of the HTML above: there is a no-js class on the <html> element. Modernizr first removes this and replaces it with a js class, which could be useful in your CSS. Along with the js class, it adds classes for all the features the browser supports and for the features it does not support, pre-fixing those with no-.

Here are two examples, one from Chrome 16 and one from IE9:

Figure 3: Modernizr’s feature detection in Chrome 16
Figure 4: Modernizr’s feature detection in IE9

Do Some Detecting

Modernizr creates a global Modernizr JavaScript object, which allows us to query different properties of that object to perform feature detection by calling Modernizr.<featurename>. So to test for canvas support, you would write the following:

So try this page in a modern browser and there will be a nice message for you.

Because you’re all good developers and write unobtrusive, progressive JavaScript so that everyone can use your site, you also want to check if canvas is not supported. You have a couple of options here. You could use the above if statement along with an else statement, like so:

Or if you want to test purely for no canvas support, you can negate the condition like this:

Feature Detection and Polyfilling with YepNope

In the examples above, you’ve seen the simplest way to detect a browser feature. What if you wanted to detect a feature and use a polyfill to make the browser perform better? You can do this with YepNope.

YepNope is a conditional loader, which means it will only load the scripts that are needed by the browser. And it’s built into Modernizr, so you don’t have to worry about downloading and linking to another JavaScript file.

So how do you use it?

Using canvas as an example again, you’ll generally want a fallback for non-supporting IE8 and below. The usual way of doing this would be to link to a JavaScript polyfill, such as FlashCanvas in your HTML:

The problem with this approach is that all browsers will download this script. That’s unnecessary and should be avoided where possible. You could arguably wrap the <script> element in conditional comments, but if you can keep the files out of the markup altogether, then you should. You can do this using Modernizr.load(). Modernizr has YepNope built into it, so you can easily test for a feature and then supply a polyfill.

So let’s take a look.

You should note that .load() is not included in the development file by default. You need to include it and build it yourself.

The basic use of the .load() function allows you to test for a feature and ask whether it’s true (yep) or false (nope). In this example, Modernizr tests for canvas support, and if the feature doesn’t exist, then it loads FlashCanvas:

So open up IE8, take a look at the network tab (Figure 5) in the developer tools. With the above code, you’ll see that it downloaded and initialised flashcanvas.js. Pretty nifty, yes?

Figure 5: FlashCanvas resources loaded in IE8

Here’s a more practical example that detects the support of <input type="date">. If it isn’t supported, it loads in two jQuery files and a CSS file to generate a styled date picker:

This test looks for <input type="date"> support. When it fails, it loads in the two external jQuery JavaScript files and a local CSS file. (Our tests suggest that the CSS file needs to be local.) Once it’s done that (i.e., on complete), it then calls the plugin for each <input type="date"> in the DOM. In most browsers, the jQuery will be loaded (Figure 6), but in Opera, the files aren’t loaded because it has a native calendar control (Figure 7):

jQuery date picker widget

Figure 6: jQuery date picker widget in Firefox
Opera date picker widget

Figure 7: Native date picker widget in Opera

The two figures below show the difference in which resources the browsers downloads:

Resources loaded in Firefox

Figure 8: Date picker resources loaded in Firefox
Resources loaded in Opera

Figure 9: Date picker resources loaded in Opera

Notice how the two jQuery JavaScript files are loaded twice. That’s a YepNope behaviour, first loading the resource and then executing it. So don’t worry, that’s normal.

You can do much more with YepNope. Here’s an example taken from the YepNope web site of all the possible properties, all of which are optional:

Conclusion

Modernizr is a powerful feature detection library. It allows you to check whether a browser supports various features and, depending on what you want to achieve, lets you use a polyfill. This article looked at how to generate a Modernizr JavaScript file and examined two different ways of using Modernizr: directly using the Modernizr object (Modernizr.<featurename>) and then using the built-in YepNope.

So, what do you think? Let us know in the comments below!

Resource

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA