.. or, why I like it.

When developing for the web, I've always been a fan of checking for functionality using object detection, I NEVER try to detect which browser you are using.

Modernizr does this much better that the other methods I've seen (and used).

Modernizr is a small JavaScript library that detects the availability of native implementations for next-generation web technologies, i.e. features that stem from the HTML5 and CSS3 specifications.

  1. It tests for over 40 next-generation features, all in a matter of milliseconds
  2. It creates a JavaScript object (named Modernizr) that contains the results of these tests as boolean properties
  3. It adds classes to the html element that explain precisely what features are and are not natively supported
  4. It provides a script loader so you can pull in polyfills to backfill functionality in old browsers
As stated above, Modernizr adds classes to the HTML tag, one per feature, pre-fixing the one that's not supported in the browser with "no-". This is the classes added to the HTML tag when I open a page in;

Chrome 17.0.942.0 dev:

<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">

Firefox 8.0.1:

<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase no-indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">

Safari 5.1.1 (7534.51.22):

<html class="js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop no-websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms no-csstransforms3d csstransitions fontface video audio no-localstorage no-sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">

IE9

<html class="ie ie9 js no-flexbox canvas canvastext no-webgl no-touch geolocation postmessage no-websqldatabase no-indexeddb hashchange no-history draganddrop no-websockets rgba hsla multiplebgs backgroundsize no-borderimage borderradius boxshadow no-textshadow opacity no-cssanimations no-csscolumns no-cssgradients no-cssreflections csstransforms no-csstransforms3d no-csstransitions fontface video audio localstorage sessionstorage no-webworkers no-applicationcache svg inlinesvg smil svgclippaths">

Lot's of red for IE9, but this is not a "which brower is best" article, but how you can use Modernizr to give the user the experience expected which ever browser she is using today or tomorrow. Eg:

[css]
.no-cssgradients .glossy { // Internet Explorer
background: url("images/glossybutton.png");
}

.cssgradients .glossy {
background-image: linear-gradient(top, #555, #333);
}
[/css]

You can also use Modernizr to load the JavaScript libraries needed:

[javascript]
Modernizr.load({
test: Modernizr.geolocation,
yep : 'geo.js',
nope: 'geo-polyfill.js'
});
[/javascript]

A bit more advanced example

[javascript]
// Give Modernizr.load a string, an object, or an array of strings and objects
Modernizr.load([
// Presentational polyfills
{
// Logical list of things we would normally need
test : Modernizr.fontface && Modernizr.canvas && Modernizr.cssgradients,
// Modernizr.load loads css and javascript by default
nope : ['presentational-polyfill.js', 'presentational.css']
},
// Functional polyfills
{
// This just has to be truthy
test : Modernizr.websockets && window.JSON,
// socket-io.js and json2.js
nope : 'functional-polyfills.js',
// You can also give arrays of resources to load.
both : [ 'app.js', 'extra.js' ],
complete : function () {
// Run this after everything in this group has downloaded
// and executed, as well everything in all previous groups
myApp.init();
}
},
// Run your analytics after you've already kicked off all the rest
// of your app.
'post-analytics.js'
]);
[/javascript]

Finally, to learn more about Modernizr and the philosophy behind it, you should watch this presentation by Faruk Ates, the creator of Modernizr:

Resources: