With the release of version 2.0, the Modernizr JavaScript library continues to gain traction as the solution of choice for advanced browser feature detection. For those of you who haven’t been properly introduced, Modernizr uses the latest JavaScript object detection techniques to discover if a feature is available before you use it, thus allowing for graceful degradation or progressive enhancement of your web pages. It is especially useful in assessing emerging web technologies such as CSS3 and HTML5 so that you can fully exploit modern browser capabilities while providing more basic content to older browsers.
How It Works
The now obsolete traditional method of doing “UA sniffing” was to identify a browser based on its navigator.userAgent property. That has proved to be quite ineffective as browser makers began to impersonate other browsers for various reasons. Modernizr does not even attempt to determine the browser make. Instead, it employs feature detection to reliably discern what the various browsers can and cannot do.
The obsolete UA sniffing approach:
if (document.all) { // IE4 height = document.body.offsetHeight; } else if (document.layers) { // NN4 height = window.innerHeight; } else { // other height = 0; }
The more precise feature sniffing method:
if (document.querySelector) { element = document.querySelector(selectors); }
Using Modernizr
If you haven’t already done so, you can download Modernizr directly from their website. There is a Development version to experiment with. Then, when you’re ready for production, you can pick and choose only the functionality you need. The “Generate!” button launches a build tool that produces minimized production-ready source code. A “Download Custom Build” button will appear when the code is ready for downloading.
Include your downloaded Modernizr library in your page’s <head> section, add the “no-js” class to the <html> element, and you’re ready to use it! You may want to rename the file to something more descriptive. My custom generated file was named “modernizr.custom.78434.js”. I would call it something like “modernizr-2.0.6.min.js” as I did here:
<!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8"> <title>HTML 5 and CSS3 Test Page</title> <script src="modernizr-2.0.6.min.js"></script> </head>
The “no-js” class acts as a fallback if JavaScript is disabled. Otherwise, once that page is loaded on the browser, Modernizr will replace it with something like the following:
<html lang="en" dir="ltr" id="modernizr-com" 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">
It’s easy enough to verify. An HTML/JavaScript debugger, such as Firebug in Firefox, will display the updated markup:
Testing for Object and Property Support
Modernizr creates a global property for each feature that it tests for. You can refer directly to these properties to check whether the browser supports the object its properties. Here’s some code that checks support for the canvas object:
if (Modernizr.canvas) { // enhance! } else { // degrade gracefully... }
The next example checks for the “text” property of the canvas object:
if (Modernizr.canvastext) { // enhance! } else { // degrade gracefully... }
Updated CSS
As you may be aware, when the browser doesn’t recognize a CSS property, it simply ignores it. Therefore, you can already use very advanced and specific properties like canvas-text. However, Modernizr does afford you more control over the page’s appearance and behavior such as allowing you to change some properties based on browser support for some associated property.
Here is some CSS for styling a glossy button. The .glossy element rule is first defined for the most basic version using the no-js class. The “.no-cssgradients .glossy” rule makes use of Modernizr to implement the glossy effect using an image. Finally, the “.cssgradients .glossy” rule styles the button using the supported .cssgradients class to increase specificity and assign a CSS gradient instead:
.no-js .glossy, .no-cssgradients .glossy { background: url("glossybutton.png"); } .cssgradients .glossy { background-image: linear-gradient(top, #555, #333); }
Modernizr 2 Features
The version 2 release contains a few new additions, including:
- Conditional Resource Loading: It allows the page to conditionally load JavaScript or CSS files depending on support for one or more browser features.
- Media Query Testing: Web page design uses CSS media queries to respond to the dimensions of the browser viewport.
- New Plugin API: You can write your own test methods for features not supported by Modernizr.
- Vendor Prefix Detection: The .prefixed() method returns the appropriate prefixed or non-prefixed name variant for a property supported by the browser.
Criticisms
Not everyone loves Modernizr. Some developers who are of a more purist mind set feel that the use of JavaScript to test CSS support is flawed from the get-go since the browser does not depend on JavaScript to render CSS styles. In fact, they make a valid point that, thanks to CSS’s inherent graceful degradation, it is quite possible to construct your style rules in such a way that will provide visitors with as rich an experience as their browsers can afford them. In that sense, it would make more sense to call Modernizr a JavaScript DOM tester than one for true CSS.
Conclusion
Whatever you want to call it, there can be little doubt that Modernizr is a highly useful tool even with its reliance on JavaScript. It should also be noted that others are climbing into the ring with similar frameworks. You may also want to check some of those out for comparative purposes.