HTML5 feature detection aka Modernizr

Tuesday 08 November 2011

Yesterday I blogged about using the new Server-Sent Events or the EventSource object to send messages from the server to the client. But what happens if I try to do this in a browser that doesn’t support Server-Sent Events?

If I run the code from yesterday in Internet Explorer 9 I sill see the following error dialog:


The reason is that IE 9 doesn’t support Server-Sent Events, see, so it results in an Microsoft JScript runtime error: 'EventSource' is undefined exception

HTML5 Feature detection

In the old days if web development we used to check the browser the client was using and make decisions based on the bowser type and version. These days that is no linger a recommended approach as browsers are updated frequently and keeping up to date base on browser versions would be a nightmare.

A better approach, and much more common these days.. is feature detection. Feature detection basically checks if a specific feature is available in a given browser. And because that uses tests based on the official API it is much easier to maintain and more reliable as it doesn’t depend on specific browsers.

In the case of the Server-Sent Events we can check for the existence of the EventSource object using the following test:

   1: if (window.EventSource) {
   2:     // Good to go
   3: }
   4: else {
   5:     // Oops
   6: }

This would work just fine but it means we have to create checks and make sure these work in every browser.

Modernizr to the rescue

Fortunately we don’t have to do so ourselves but we can use the excellent Modernizr JavaScript library. Modernizr contains checks for almost all HTML 5 you might want to test for and will make sure the tests are checked against all relevant browsers. And to make live easy for the ASP.NET MVC developers the team decided to add Modernizr to the standard HTML5 project template so you get it automatically. If you don’t have it yet it is easy to add to an existing project through the NuGet package.


The developers solution

Developer write code for their day to day business so as a developer when I have a problem I am going to write some code to solve this problem. By adding Modernizr to the mix and adding a simple check we can use the following code and get the result below.

   1: if (Modernizr.eventsource) {
   2:     var source = new EventSource('home/events');
   4:     source.onmessage = function (e) {
   5:         $('<li>').text('#messages');
   6:     };
   8:     source.addEventListener('ping', function (e) {
   9:         $('<li>').text('#messages');
  10:         console.log(;
  11:     }, false);
  12: }
  13: else {
  14:     $("<li>This browser doesn't support Server-Sent Events</li>").css('color', 'red').appendTo('#messages');
  15: }


Not bad but we can do even better Smile


Besides the Modernizr object where we can check of features the library actually adds or removes CSS classes to the root <html> we can use to style element. When a feature exists it adds a class with the same name as the feature, eventsource in this case, if it doesn’t it add as class no-eventsource instead. Using this we can actually start showing or hiding elements using just CSS and no JavaScript code.

Suppose I use the following HTML:

   1: <style>
   2:     html.eventsource .warning
   3:     {
   4:         visibility: hidden;
   5:     }
   6: .warning
   7:     {
   8:         background-color: Red;
   9:     }
  10: #messages
  11:     {
  12:         visibility: hidden;
  13:     }
  14: </style>
  15: <div class='warning'>
  16:     This browser doesn't support Server-Sent Events</div>
  17: <ol id='messages'>
  18: </ol>

We get the following result:


You can even test for JavaScript being enabled this way. If it is Modernizr will remove a no-js class in the <html> element and add a js class. Of course if JavaScript is disabled Modernizr can’t add a css class to you must add the no-js class yourself.

The general recommendation for JavaScript is to add it at the bottom of the page, after all content but these CSS classes are the reason you should make an exception for Modernizr and always add that to the <head> of your page.


When doing HTML 5 work you just have to live Modernizr Smile