As I continue preparing developer guidance for ASP.NET Developers who want to use HTML features in their ASP.NET applications, I’m reminded that public facing web sites need to support legacy bowsers while offering the up-to-date visitors with the better experience that the latest technologies can provide.

Though we might keep a server-side index of supported features on a per browser basis, it makes more sense to dynamically detect feature support on an as-needed basis.

Why ?

  • Feature detection by JavaScript in the browser is the most accurate, up-to-date means to determine the availability of a feature.
  • You only have to write the detection code once for each feature.
  • You don’t need to create and continually update the server side feature matrix on a “per browser” basis.

I’ll be sharing code snippets and blogging about using HTML5 specific features but in this post I’ll be sharing a sample of using HTML feature detection.

The code below is intended as a generic example bit I will use the HTML5 Video Tag to demonstrate the techniques.

EXAMPLE: Some browsers simple do not support the HTML5 Video Tag at all. Others support the Video Tag but only render specific video file types.

Rather than only support users who are using our favorite browser, wehave several options to provide the broadest possible browser support.

Our fist option is to write some JavaScript code to find out if the specific features (HTML5 Video in this case) is available.


<!DOCTYPE html>
 <html lang="en">
   <head>
      <script>
    //---------------------------------------------------------------------
     function supports_ogg_video()
    {
          if (!supports_video())
             {
             return false;
             }
         var v = document.createElement("video");
          return v.canPlayType('video/ogg; codecs="theora, vorbis"');
       }
  
       function supports_video()
       {
          return !!document.createElement('video').canPlayType;
       }
  
       //---------------------------------------------------------------------
       function test()
       {
           var txt = document.getElementById("statusDiv");
           var outputtext = "Test .....";
           var yesno = supports_video();
           if (yesno)
              {
              txt.innerHTML = "HTML5 Video IS Suported.<br />";
              yesno = supports_ogg_video();
              if (yesno == "")
                 {
                 txt.innerHTML = "The OGG Video Format is Not Suported.<br />"
                 txt.innerHTML += "Use different format, ";
                 txt.innerHTML += "Silverlight or Flash !!!";
                 }
              else
               {
               txt.innerHTML += "The OGG Format is " + yesno + " suported.";
               }
             }
         else
             {
             txt.innerHTML = "HTML5 Video Not Suported.<br />";
             txt.innerHTML += "Add Silverlight or Flash Logic Here !!!";
             }
     }

     //---------------------------------------------------------------------
     onload=function()
     {
      test();
     }

     </script>
   </head>
   <body>
           <br /><br />
             <div id="statusDiv"></div>
    </body>
 </html>
  

In the code above were are specifically ascertaining the browsers support for HTML5 using the .OGG file type.

The test() function is where you would actually emit the HTML5 specific markup or, if HTML5 Video or the OGG file format are not supported we would fall back to some other video strategy like inserting the WMV player or using a Silverlight plugin.

Note that test() is automatically called when the page loads via the onLoad event (see line #50).

After a bit of prep work we see if the current browser has NAY support for the HTML Video tag.

In order to make this determination we try to programmatically create a <video> element.

If we are unable to do so that the HTML5 <video> element is not supported by the browser.

IF we can create a <video> element, we can now try to determine if that element supports .OGG files.

We do this by calling the function supports_ogg_video()

You will note that, for demonstration purposes I have can redundantly called supports_video().

I could eliminate the call at line 26 (and the related “if” logic) and only call supports_ogg_video()  because it checks for overall video element support.

This works fine, but is a little cumbersome.

Let me introduce you to a FANTASTIC JavaScript library – Modernizr

Modernizr is a simple but powerful library that does all the modern browser feature detection for you.

Lets look at what the page above would look like using Modernizr.


<!DOCTYPE html>
  <html lang="en">
    <head>
      <script type="text/javascript" src="modernizr-1.6.min.js"></script>
        <script>
      //---------------------------------------------------------------------
      function test()
      {
          var txt = document.getElementById("statusDiv");
          var outputtext = "Test .....";
          if (Modernizr.video)
             {
             txt.innerHTML = "HTML5 Video IS Suported.<br />";
              if (Modernizr.video.ogg)
                {
                txt.innerHTML += "The OGG Format is " + yesno + " suported.";
                }
             else
                {
                txt.innerHTML = "The OGG Video Format is Not Suported.<br />"
                txt.innerHTML += "Use another format, Silverlight or Flash.";
                 }
               }
           else
               {
               txt.innerHTML = "HTML5 Video Not Suported.<br />";
               txt.innerHTML += "Add Silverlight or Flash Logic Here !!!";
               }
       }
  
       //---------------------------------------------------------------------
       onload=function()
       {
        test();
       }
       </script>
     </head>
     <body>
         <br /><br />
          <div id="statusDiv"></div>
     </body>
   </html>
  

 
Note lines 11 and 14.
VIOLA !
 
Note the simplicity and the code reduction.
 
I’ll assume that the advantages of using Modernizr in these instances is obvious, but I’ll take our problem solving one step further.
 
In the case of some HTML5 specific features – graceful degradation is built in and this is the case with the Video Element in HTML5.
 
Consider the following HTML5 markup.
 

<!DOCTYPE html>
<html lang="en">
  <head>
  </head>
  <body>
	<video controls="controls">
		<source src="windowsmedia.wmv">
		<source src="windowsmedia.ogg">
		<p>
		   <object width="240" height="196">
			   <param name="loop" value="false">
			   <param name="playeveryframe" value="true">
			   <param name="cache" value="true">
			   <param name="controller" value="false">
			   <param name="autoplay" value="true">
			   <param name="src" value="windowsmedia.wmv">
			   <embed src="windowsmedia.wmv" autoplay="true"
							 controller="false"
							 cache="true"
							 type="application/x-mplayer"
							 playeveryframe="true"
						         loop="false"/>
		   </object>
	   </p>
   </video>
 </body>
</html>

Understand that lines 9 through 24 are only to support the circumstance when the browser does NOT support the HTML5 video tag using WMV files of OGG files.

If the browser is unable to play WMV files specified in the <video> tag it will try to play the .OGG file. If that is also not supported (or if the <video> tag is not supported at all, the paragraph <p> will be emitted and, in our case, the video will play using the Windows Video Player.

Of course, not all HTML features will support tis sort of fallback support.

In my HTML5 coding i’’ll be implementing the following fallback hierarchy.

  1. User HTML5 built in fall back when ever available.
  2. In no HTML fallback support – use Modernizr
  3. If no Modernizr support for the features – use the Do-It-Yourself method.