Safely Deploy HTML5 and CSS3 with Modernizr
As the new HTML5 and CSS3 Web standards come online, surfers can expect to see some exciting new functionality and more elegant page layouts. Of course, there is a catch for developers: complete Web browser support for these standards won’t exist for awhile. Compound that with the fact that many Web users are slow to upgrade their browsers, and it is no surprise that implementing HTML5 or CSS3 functionality is problematic.
In the past developers have accessed the navigator.userAgent property in JavaScript to determine which Web browser and version the client was using. This practice is called browser sniffing, and it has allowed the developer to quickly fork code during page rendering to side-step display inconsistencies among browsers. Browser sniffing and version detection are not an elegant solution, however, because they ensure a maintenance nightmare further down the road. Vendors are pushing out new versions of their respective browsers at a rapid rate, so chances are that your built-in exceptions handling is soon obsolete.
A better approach is to conduct feature detection. Instead of asking the browser “Who are you?” and proceeding from there, feature detection asks the browser, “What can you do?”. Modernizr is an open-source JavaScript library that makes feature detection simple. This means that developers can take advantage of HTML5 / CSS3 features in those browsers that support them without sacrificing control over the user experience in other browsers.
A JavaScript object called Modernizr is created on page load to itemize the native availability of HTML5 / CSS3 features.
Say, for instance, we want to produce some nice, JD recommended, client-side graphs using the RGraph library. Then we can use Modernizr to tell us whether the browser supports the HTML5 Canvas element. If it does, great, and if it doesn’t, wellthen we can make the graphs by alternative means without interfering with the client’s browsing experience.
if (Modernizr.canvas) {
// Start drawing!
var context = $('my-canvas').getContext( '2d' );
context.fillStyle = "rgb(255,0,0)";
context.fillRect( 10, 10, 10, 10 );
...
} else {
// Call a server-side script to produce the image instead
}
Similarly, we could revisit Michael’s HTML5 GeoLocation Google Maps script, and replace his navigator.geolocation check with the following:
if (Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition( success, fail );
}
While this is technically the same thing, it is nice for developers to only have to reference one object to identify a feature’s availability.
Looking at Jeff’s HTML5 placeholder text input attribute, we know that it degrades gracefully (i.e., is ignored) if the browser doesn’t support it. But what if we want to ensure that the client always sees a placeholder in the text field? Then we could use Modernizr to detect placeholder attribute support, and if it doesn’t exist, resort to a simple script that does much the same thing:
if (!Modernizr.input.placeholder) {
setPlaceholder( $('address'), 'Enter your address...' );
}
Modernizr detects support for a wide range of HTML5 / CSS3 features, but it does not add missing functionality to browsers. It does add support for styling and printing HTML5 elements. It also comes to the aid of designers who have always wished there were if-then statements in CSS. Let’s say we want to use the CSS3 box-shadow feature. Yes, it does just what it’s name suggests and adds a shadow around a box. When Modernizr first runs, it adds classes to the HTML page element that indicate all of the features it detects. So the HTML element might looks something like this:
<html class="js canvas no-geolocation rgba boxshadow no-opacity ...">
Notice that features that aren’t available are prefaced with “no-”. Using cascading, we can add the box-shadow to the CSS stylesheet as follows:
div.my-div {
/* Simulate a box-shadow using borders */
border-bottom: 1px solid #666;
border-right: 1px solid #777;
}
.boxshadow div.my-div {
/* Do it natively instead */
border: none;
box-shadow: #666 1px 1px 1px;
-moz-box-shadow: #666 1px 1px 1px;
-webkit-box-shadow: #666 1px 1px 1px;
}
The native box-shadow style is never even parsed if it isn’t available. Simple.
Finally, the Modernizr object also contains more detailed information about certain features like video. Can the client’s browser handle H.264 encoded video? Reference the Modernizr.video.h264 property and you will quickly know. Can this syntax be any more intuitive?
Modernizr is only 3.9kB in size. Using it makes obvious sense for a development shop that chooses to be proactive in adopting HTML5 and CSS3 functionality. Modernizr provides the ability to transparently support different levels of site experience based on the capabilities of each visitor’s browser without resorting to browser sniffing.
