This is the third in a series of articles dedicated to useful libraries that all web developers should have in their toolbox. The intent is to show you what those libraries can do and help you to use them at their best. This third article is dedicated to the Modernizr library.
Introduction
Modernizer is a library originally written by Faruk Ateş.
It is one of the key libraries for building cross-browser websites or applications in a modern fashion. The heart of the library is the web design pattern known as Progressive enhancement & Graceful degradation. This design pattern does not require Modernizr, but Modernizr can make things a lot easier. It detects the availability of native implementations for next-generation web technologies such as HTML5 or CSS3 and allow you to adapt your application accordingly, which is way better than trying some ugly voodoo user-agent sniffing.
Basic usage
Using this library is amazingly simple: Download it, link it to your pages—you’re done!
Modernizr will automatically add some CSS classes to the root html
element. For example if you want to test Web Sockets support, it will add a websockets
class to the html
element if the browser supports that feature, otherwise it will add the no-websockets
class. It will do the same with JavaScript by adding a global variable Modernizr.websocket
with a boolean value.
Let’s see a simple example: Doing some stuff with RGBa colors.
First: Download a customized version of Modernizr
Second: Link it to your document
<!DOCTYPE html> <!-- The "no-js" class is here as a fallback. If Modernizr is not running, you'll know something is wrong and you will be able to act accordingly. In contrast, if everything goes well, Modernizr will remove that special class. --> <html class="no-js"> <head> <meta charset="utf-8"> <title>I want to do stuff with RGBa</title> <script src="modernizr.js"></script> </head> <body> ... </body> </html>
Third: Use it
With CSS
.rgba div {
/* Do things with CSS for browsers that support RGBa colors */
}
.no-rgba div {
/* Do things with CSS for browsers that DO NOT support RGBa colors */
}
With JavaScript
if(Modernizr.rgba) {
// Do things with JS for browsers that support RGBa colors
} else {
// Do things with JS for browsers that DO NOT support RGBa colors
}
Let’s see this silly example in action:
%CODEtoolbox-3-1%
Advanced usage
The basic usage is already awesome when you have to deal with a heterogeneous environment (such as mobile browsers for example), but there’s more.
Conditional loading
Modernizr offers a convenient way to do conditional loading. Actually, the YepNope library is a standalone spin-off of the Modernizr project. So, if you wish, you can bundled YepNope directly inside Modernizr. It’s perfect if you want to load based polyfills depending on specific browser capacity.
Modernizr.load({
test: Modernizr.indexeddb,
nope: "indexeddb-polyfill.js"
});
This is a very powerful tool: do not hesitate to read the documentation. Note that the Modernizr team maintain a list of very accurate polyfills. Feel free to use whatever you need (with caution, of course).
Custom tests
Modernizr come with a set of 44 tests for mainstream technologies. If you need to test some other technologies, Modernizr provide an API to build and plug your own tests.
// Let's test the native JSON support ourselves Modernizr.addTest('json', function(){ return window.JSON && window.JSON.parse && typeof window.JSON.parse === 'function' && window.JSON.stringify && typeof window.JSON.stringify === 'function'; });
Assuming the above test passes, there will be now a json
class on the HTML element and Modernizr.json
will be true. Otherwise, there will be a no-json
class on the HTML element and Modernizr.json
will be false.
Dealing with CSS prefix
CSS prefixes is a very sensitive subject. Modernizr provides cross-browser code to take care of this issue. Modernizr offers a very useful tool to deal with this: Modernizr.prefixed(). This method works with CSS properties (in the CSS OM camelCase style) as well as with DOM properties.
For example, Modernizr.prefixed("transition")
will return “MozTransition” with Firefox but “WebkitTransition” with Safari and Chrome.
Testing media-queries
There is currently no simple way to test a media query from JS in any browser. To help with that, Modernizr has a special tool: Modernizr.mq()
. This method will test the media query of your choice and will return true or false accordingly.
if(Modernizr.mq("screen and (max-width: 400px)")) {
// Do some stuff for small screens
}
Limits and precautions
This library is a fantastic tool but it’s not magic. You should use it with caution and do not forget about other techniques to deal with unpredictable behaviors. For example, do not forget to rely on the CSS cascade when it’s sufficient.
The following example is a huge misuse of Modernizr:
div {
color : white;
}
.rgba div {
background : rgba(0,0,0,.8);
}
.no-rgba div {
background : #333;
}
If for some reason Modernizr is not executed, your text will not be readable (white text over a white background). In this specific case, you are better doing the following (which, by the way, is also easier to read and maintain):
div {
color : white;
background : #333;
background : rgba(0,0,0,.8);
}
So, don’t be blind when you use this library, take the time to think about what will happen if Modernizr is not available. In many case you have existing fallbacks, don’t forget to use them.
Conclusion
Modernizr is the most useful tool when you have to build large cross-browser stuff, from the oldest Internet Explorer 6 to the latest Firefox Nightly. Once you master it, you will be able to add some magic to your sites and applications. However, as with all the powerful tools, it takes some time to become comfortable with and to use it wisely at its full potential. But, Modernizr is definitely worth the effort.
About Jeremie Patonnier
Jeremie is a long time contributor/employee to the Mozilla Developer Network, and a professional web developer since 2000. He's advocating web standards, writing documentation and creating all sort of content about web technologies with the will to make them accessible to everybody.
16 comments