Chapter 1. Getting Started with Modernizr

Are you tired of approaching the way you build your websites as though it was two or maybe three years ago? By that I mean not building the experience as if it were for the browser of today, but instead building it for the oldest browser your users are most likely to be navigating with. Are you also tired of building different versions of the same website for an abundance of browsers, by version, and then stuffing them full of CSS hacks? What if there was a better and more manageable way?

What if you could build something not only for three years ago, but also for today? What if you could even build it for as far into the future as three years from now? What if you could do this without having to do any sort of browser sniffing at all? I'm very happy to say that this is possible today, thanks to the concept of feature detection and a lightweight, customizable detection library named Modernizr.

In this chapter we will cover the following topics:

  • What is feature detection?
  • What is Modernizr?
  • The Modernizr namespace; storing the test results.
  • CSS selector test results.
  • Designing for the feature and not the browser.
  • Why UA sniffing is bad.

Detect and design with features, not User Agents (browsers)

What if you could build your website based on features instead of for the individual browser idiosyncrasies by manufacturer and version, making your website not just backward compatible but also forward compatible? You could quite potentially build a fully backward and forward compatible experience using a single code base across the entire UA spectrum. What I mean by this is instead of baking in an MSIE 7.0 version, an MSIE 8.0 version, a Firefox version, and so on of your website, and then using JavaScript to listen for, or sniff out, the browser version in play, it would be much simpler to instead build a single version of your website that supports all of the older generation, latest generation, and in many cases even future generation technologies, such as a video API, box-shadow , first-of-type, and more.

Tip

Think of your website as a full-fledged cable television network broadcasting over 130 channels, and your users as customers that sign up for only the most basic package available, of only 15 channels. Any time that they upgrade their cable (browser) package to one offering additional channels (features), they can begin enjoying them immediately because you have already been broadcasting to each one of those channels the entire time.

What happens now is that a proverbial line is drawn in the sand, and the site is built on the assumption that a particular set of features will exist and are thus supported. If not, fallbacks are in place to allow a smooth degradation of the experience as usual, but more importantly the site is built to adopt features that the browser will eventually have. Modernizr can detect CSS features, such as @font-face , box-shadow , and CSS gradients. It can also detect HTML5 elements, such as canvas , localstorage , and application cache . In all it can detect over 40 features for you, the developer.

Another term commonly used to describe this technique is "progressive enhancement". When the time finally comes that the user decides to upgrade their browser, the new features that the more recent browser version brings with it, for example text-shadow, will automatically be detected and picked up by your website, to be leveraged by your site with no extra work or code from you when they do. Without any additional work on your part, any text that is assigned text-shadow attributes will turn on at the flick of a switch so that user's experience will smoothly, and progressively be enhanced.

Note

What is Modernizr? More importantly, why should you use it? At its foundation, Modernizr is a feature-detection library powered by none other than JavaScript.

Here is an example of conditionally adding CSS classes based on the browser, also known as the User Agent. When the browser parses this HTML document and finds a match, that class will be conditionally added to the page.

<!--IE only conditional comments http://www.quirksmode.org/css/condcom.html -->
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class=" lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="lt-ie9"> <![endif]-->

Now that the browser version has been found, the developer can use CSS to alter the page based on the version of the browser that is used to parse the page. In the following example, IE 7, IE 8, and IE 9 all use a different method for a drop shadow attribute on an anchor element:

/* IE7 Conditional class using UA sniffing */
.lt-ie7 a{ display: block; float: left; background: url( drop-shadow.gif ); }
.lt-ie8 a{ display: inline-block; background: url( drop-shadow.png );  }  
.lt-ie9 a{ display: inline-block;  box-shadow: 10px 5px 5px rgba(0,0,0,0.5); }

The problem with the conditional method of applying styles is that not only does it require more code, but it also leaves a burden on the developer to know what browser version is capable of a given feature, in this case box-shadow. Here is the same example using Modernizr. Note how Modernizr has done the heavy lifting for you, irrespective of whether or not the box-shadow feature is supported by the browser:

/* Box shadow using Modernizr CSS feature detected classes */

.box-shadow a{ box-shadow: 10px 5px 5px rgba(0,0,0,0.5); }
.no-box-shadow a{ background: url( drop-shadow.gif ); }

The Modernizr namespace

The Modernizr JavaScript library in your web page's header is a lightweight feature library that will test your browser for the features that it may or may not support, and store those results in a JavaScript namespace aptly named Modernizr. You can then use those test results as you build your website.

From this point on everything you need to know about what features your user's browser can and cannot support can be checked for in two separate places. Going back to the cable television analogy, you now know what channels (features) your user does and does not have, and can act accordingly.

The following screenshot shows the Modernizr object from the console:

The Modernizr namespace

Modernizr is storing either true or false properties inside its namespace based on the features that the browser supports, which can in turn be used to tightly and easily control the user's experience.

The first place you can use to check for support is, of course, the Modernizr JavaScript object now available on the page. Let's say, for example, you wanted to know if the viewer of your web page has support for 3D CSS transformations within the browser (user agent) they are using. Checking for this is as simple as a conditional in your JavaScript code, as shown in the following code snippet:

//JavaScript test for 3D CSS Transformations.if( Modernizr.csstransforms3d ){console.log('3D CSS Transformations are supported!'),}

Modernizr has stored this as a property of either true or false, and by checking the result of this test, we are able to ascertain if the browser that any particular user is accessing your web page with has that feature supported. If they do, great! If they don't, then we can degrade the experience a bit so they aren't left viewing a big empty box on the page, and the best part is that once they do inevitably upgrade, all of the really cool features will be there, ready and waiting.

After the Modernizr library feature tests have run on your page, there will be a great number of test results now stored as properties in the Modernizr JavaScript namespace. In fact, at the time of this writing, over 40 feature tests were performed by this lightweight, lightning fast library, not counting the additional extensions available in the user community for even more feature tests, for example, CSS3 media queries. The following screenshot shows an example from the JavaScript console that is testing for CSS gradients and logging a success message if they are supported:

The Modernizr namespace

Modernizr version 2.5 tests over 40 next-generation features, which means that there are over 40 applications you can build for today that aren't even available yet in many of the current browsers.

Supporting features with CSS selectors

It doesn't stop at JavaScript either. There is a second way to leverage the feature tests from Modernizr. You see that what Modernizr has also done behind the scenes is added a series of CSS selectors to the HTML element of the web page. By inspecting the element in the browser and viewing the Document Object Model (DOM), you'll see that Modernizr was also hard at work on the DOM tree in addition to the JavaScript, and has added a selector to the HTML element for all of the feature tests that were performed.

If I inspect an element in Google Chrome 19 for example, I get the following code snippet added to the HTML element of my DOM tree:

<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 generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths"...

The whole mess of selectors that you see are the feature tests, which Modernizr ran and has now stored as properties within its namespace. Now that they are additionally inside the DOM, there is a second capability available for use. We can now create style conditions around these functionalities from the stylesheet as well.

It's not limited to pass the tests either. Let's see what happens when I run that exact same Modernizr script in Internet Explorer 8 using Windows 7 as my environment:

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

Now that's a whole lot of selectors and a whole lot of no's! Let's look at some key differences between the two examples. You see Modernizr not only adds in its own classes for the features that are supported but also for the features that are not supported.

For example, Internet Explorer 8 does not support the CSS 3D transformations (and won't until version 10), previously tested for and supported in Google Chrome 19, and as such Modernizr has added a no-csstransforms3d class to the HTML element.

All other CSS features that are supported and not supported have been added as well. For example, CSS gradients are also unsupported by this version of Internet Explorer, and therefore a class of no-cssgradients has been added, and a fallback can be created via the stylesheet. Using this you can do something as extreme as hiding elements that use this feature, or as mild as providing an alternate view to the user.

By taking advantage of the no-cssgradients class that was added for us by our lovely feature-detection library, we can enhance the experience and do it all once from one stylesheet if we like; more on that later.

Here is an example of using CSS to progressively adapt the experience for the user:

//No support for 3D transforms.no-cssgradients .header{
background-image: url('images/bg-gradient.png'),}
//Supported 3D transforms.cssgradients .header{
background-image: linear-gradient(bottom, rgb(13,25,248) 36%, rgb(39,53,255) 68%, rgb(67,80,255) 84%);
}

As you can see in the preceding example, users with browsers that support CSS gradients will have the browser render a CSS gradient, and browsers that do not will instead have a more resourceful and HTTP request-hungry PNG image as the background image.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset