Modernizr is an open source JavaScript library that allows us to test for individual features of HTML5 in our users’ browsers. Instead of testing just for a particular browser and trying to make decisions based on that, Modernizr allows us to ask specific questions like: “Does this browser support geolocation?” and receive a clear “yes” or “no” answer.
The first step to using Modernizr is to download it from the Modernizr site, at http://modernizr.com.
Once you have a copy of the script, you’ll need to include the script
file in your pages. We’ll add it to the head
in this example:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>My Beautiful Sample Page</title> <script src="modernizr-1.7.min.js"></script> </head>
You can use Modernizr in two ways: with CSS, and with JavaScript.
When Modernizr runs, it will add an entry in the class
attribute of the HTML <html>
tag for every feature it detects,
prefixing the feature with no-
if the browser doesn’t
support it.
For example, if you’re using Safari 5, which supports almost
everything in HTML5 and CSS3, your opening <html>
tag will look a little like this after
Modernizr runs:
<html class=" js flexbox canvas canvastext no-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 no-inlinesvg smil svgclippaths">
Here’s what Modernizr adds to the <html>
tag in Firefox 4:
<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 no-cssanimations csscolumns cssgradients no-cssreflections csstransforms no-csstransforms3d csstransitions fontface video audio localstorage no-sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">
To make better use of this feature of Modernizr, we should first add
the class
no-js
to our html
element in our HTML source:
<html class="no-js">
Why do we do this? If JavaScript is disabled, Modernizr won’t run at
all—but if JavaScript is enabled, the first thing
Modernizr will do is change no-js
to
js
, as we saw in the Safari 5 and
Firefox 4 samples above. This way, you’ll have hooks to base your styles
on the presence or absence of JavaScript.
You might be thinking, “That sounds pretty cool, but what am I actually supposed to do with this information?” What we can do is use these classes to provide two flavors of CSS: styles for browsers that support certain features, and different styles for browsers that don’t.
Because the classes are set on the html
element, we can use descendant selectors to
target any element on the page based on support for a given
feature.
Here’s an example. Any element with an id
of #ad2
that lives inside an element with a class
of cssgradients
(in other words, the html
element when Modernizr has detected support
for gradients) will receive whatever style we specify here:
.cssgradients #ad2 { /* gradients are supported! Let’s use some! */ background-image: -moz-linear-gradient(0% 0% 270deg, rgba(0,0,0,0.4) 0, rgba(0,0,0,0) 37%, rgba(0,0,0,0) 83%, rgba(0,0,0,0.06) 92%, rgba(0,0,0,0) 98%); … }
But what if CSS gradients aren’t supported? We could change the styling to use a simple PNG background image that recreates the same gradient look. Here’s how we might do that:
.no-cssgradients #ad2 { background-image: url(../images/put_a_replacement_img_here.png) }
Another way we could use the classes Modernizr adds to the html
element is with Drag and Drop. We discussed
Drag and Drop in Chapter 11, where we added several
images of computer mice that can be dragged onto our cat picture to be
eaten. These images are all stored in a div
with an id
of mouseContainer
.
But in Opera, where Drag and Drop will fail to work, why even show
the mouse images at all? We can use Modernizr to hide the div
if Drag and Drop is unsupported:
If Drag and Drop is supported, we simply align
all the content in the div
horizontally:
We can also use Modernizr in our JavaScript to provide some fallback if the visitor’s browser lacks support for any of the HTML5 elements you use.
When Modernizr runs, as well as adding all those classes to your
<html>
element, it will also create a
global JavaScript object that you can use to test for feature support. The
object is called, appropriately enough, Modernizr
. This
object contains a property for every HTML5 feature.
Here are a few examples:
Modernizr.draganddrop; Modernizr.geolocation; Modernizr.textshadow;
Each property will be either true
or
false
, depending on whether or not the feature is
available in the visitor’s browser. This is useful, because we can ask
questions like “Is geolocation supported in my visitor’s browser?” and
then take actions depending on the answer.
Here’s an example of using an
if
/else
block to test for
geolocation support using Modernizr:
if (Modernizr.geolocation) { // go ahead and use the HTML5 geolocation API, // it’s supported! } else { // There is no support for HTML5 geolocation. // We may try another library, like Google Gears // (http://gears.google.com/), to locate the user. }
As mentioned in Chapter 2, IE8 and earlier versions will forbid unrecognized elements to be styled. We then introduced a solution by Remy Sharp, the “HTML5 shiv,” that solves this problem. However, as we alluded to then, Modernizr also solves this problem for us!
As stated on the Modernizr documentation page:
“Modernizr runs through a little loop in JavaScript to enable the
various elements from HTML5 (as well as abbr
) for styling in Internet Explorer. Note
that this does not mean it suddenly makes IE support the audio or video
element, it just means that you can use section
instead of div
and style them in CSS.”
In other words, we now no longer need the HTML5 shiv for styling the new semantic elements in IE8 and below—if we’re using Modernizr anyway, it will take care of that for us.
To learn more about Modernizr, see:
Modernizr documentation: http://www.modernizr.com/docs/
A fairly comprehensive and up-to-date list of polyfills for HTML5 and CSS3 properties that can be used in conjunction with Modernizr is maintained at https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
A List Apart article, “Taking Advantage of HTML5 and CSS3 with Modernizr”: http://www.alistapart.com/articles/taking-advantage-of-html5-and-css3-with-modernizr/