Since the beginning of the Browsers’ War in the 1990’s, web developers have been trying to use the latest and more innovative features implemented in popular browsers. The problem was that most of those features were not available in all browsers and they had to make some “tricks” to know when to use them. In this post, I am going to discuss briefly the popular techniques used in order to detect the features supported by the browsers. Also, how this affects users with browsers that do not support them.

Past – Browser Sniffing

In the past, the two most popular browsers were Internet Explorer and Netscape. As they were competing in who was taking the market in future years, they implemented most of their features on their own without the intervention of any entity to regulate and thus made those features cross browsers. In fact, going further we can see that in the early years of HTML, there were not clear standards and browser vendors used to create HTML elements. For example, in 1993 Mosaic created tags for adding images, nested list, and forms (Raggett et. al 1998).

In order to target specific browsers, developers used the technique called browser sniffing which is a technique to know (or guess) the browser of the visitors by looking for features that are implemented in specific browsers or by navigator.userAgent to detect the name of the browser in use.

The most popular way of browser sniffing was by testing for features exclusively of that particular browser. For example, in case the developer needed to make something fancy that was only used in Internet Explorer, the use of document.all was almost always the first choice. Example:

if(document.all){
 //...do something fancy here...
} else {
 //...do something else for other browsers...
}

The good thing about this approach was that document. All was never standardized, so only Internet Explorer had it. However, as you are depending on a Non-standard feature, the feature could be removed in future releases of the browser. Also, you can have a problem if other browsers implement it.

Another alternative when targeting other browsers was checking the string returned by the navigator.userAgent and search for specific substring to give us a clue of what browser is it. Example:

if(navigator.userAgent.indexOf(“MSIE 7”) !== -1){
// ...do something fancy here...
} else{
//...do something else for other browsers...
}

There are no good things about this approach because some browsers cheat with this. For example, Opera used to return the same string as Internet Explorer in order to avoid being blocked by some websites and applications.

Present – Feature Detection

Today it hasn’t changed too much but the detection is different. Before the test was performed to verify a particular browser, now the test is to check if a certain feature is supported or available. As web development has evolved to use best practices and standards, now we detect features that we want in all the browsers to be supported instead of supported in a particular browser. In case the feature is not supported then we use a polyfill as fallback. To be clearer, today developers for expected features in all browsers because they are in the standards specifications instead of testing for non-standard features to know what browser or engine is used by the user. Example:

if(!!document.createElement(“canvas”).getContext){
 ...Canvas is supported...
} else{
 ...Use polyfill...
}

The previous code creates a canvas element and then tests if the element created has the property getContext to make sure that the element created was a canvas and it is supported by the browser.

if(String.prototype.trim){
 //...Use the trim method...
} else{
 //...Do something else...
}

This code tests the method trim before it is used. This is very popular nowadays as developers are trying to use native and standard features that are not implemented in all the browsers yet.

Feature testing is very important in professional web applications in order to deliver the best experience to the users because native implemented features always run faster and has less cross browser issues than polyfills. The good part is that there are several libraries that do it automatically for you. The most popular is Modernizr that lets you detect what HTML5 and CSS3 features are available.

Future – Native in the Browser

To my knowledge, there are not many advances right now and we as JavaScript developers have to use feature testing in order to know if they are available. Feature detection is very easy and probably it will still be used in the future. However, for those people working with CSS, there is a new CSS @supports rule which is native feature detection in CSS.

The @supports syntax is very easy and similar to the already popular media queries. Examples:

@supports(box-shadow:3px 2px 3px gray){
   #header{
     box-shadow:3px 2px 3px gray;
   }
}

The previous example tests if the browser supports the box-shadow property. In case it is supported, it would apply it to the #header. In case the property is not supported then the browser ignores it.

You can go a little further in case you want to use vendor prefixes.:

@supports(box-shadow:3px 2px 3px gray) or 
         (moz-box-shadow:3px 2px 3px gray) or
         (webkit-box-shadow:3px 2px 3px gray) or
         (o-box-shadow:3px 2px 3px gray) or
         (ms-box-shadow:3px 2px 3px gray)   {
   #header{
     webkit-box-shadow:3px 2px 3px gray;
        moz-box-shadow:3px 2px 3px gray;
         ms-box-shadow:3px 2px 3px gray;
          o-box-shadow:3px 2px 3px gray;
            box-shadow:3px 2px 3px gray;
   }
}

Using this method, you are testing vendor prefixes before you apply them.

The CSS feature detection is not implemented in JavaScript yet at the moment of this writing. However, Opera in version 12.10+ has a beta version of it.

Conclusion

In conclusion, the advantages of using @supports is that you don’t need to depend on heavy and complex feature testing frameworks in order to know when a feature is used. However, feature detection frameworks like Modernizr are not going to die. They are just going to deliver a smaller library with even more awesome features because they are going to put time and effort in other issues other than CSS feature support.

Further Details and References

This was previously posted at teylorfeliz.com

«
»