Browser Detection Versus Feature Detection

Browser detection versus feature detection

It seems to me browser detection has been widely frowned upon since this post by Resig a couple of years ago. Resig's comments however were specific to libraries/framework code, i.e. code that will be consumed by other [domain-specific] applications/sites.

I think feature detection is without question a good fit for libraries/frameworks. For domain-specific applications however I'm not so sure browser detection is that bad. It's suitable for working around known browser characteristics that are difficult to feature-detect, or for browsers that have bugs in their implementation of the feature itself. Times that browser detection is appropriate:

  • sites/applications that are not cross-browser and need to show a warning/dialog/DifferentPage tailoring to that client's browser. This is common in legacy applications.
  • Banks or private sites with strict policies on what browsers and versions are supported (to avoid known security exploits that may compromise user's data)
  • micro-optimizations: occasionally one browser is ridiculously faster than the others when performing some operation a certain way. It can be advantageous depending on your user base to branch on that particular browser/version.
  • Lack of png transparency in IE6
  • many display/rendering issues (read: IE css support) that are only witnessed in specific browser versions and you don't actually know what feature to test for.

That said, there are some major pitfalls (probably committed by most of us) to avoid when doing browser detection.

What's the difference between feature detection, feature inference, and using the UA string

Feature detection checks a feature for existence, e.g.:

if (window.XMLHttpRequest) {
new XMLHttpRequest();
}

Feature inference checks for a feature just like feature detection, but uses another function because it assumes it will also exist, e.g.:

if (document.getElementsByTagName) {
element = document.getElementById(id);
}

Checking the UA string is an old practice and should not be used anymore. You keep changing the UA checks and never benefit from newly implemented features, e.g.:

if (navigator.userAgent.indexOf("MSIE 7") > -1){
//do something
}

What is the means, benefit and differences between User Agent detection and Feature Detection?

The main reason to use feature detection as opposed to user agent sniffing is future proofing.

Let's say, for example, that you want to use some new XMLHttpRequest 2.0 features (just making this up). You know IE doesn't support it but Firefox does, and so you have code like this in your JS:

if (!IE) {
UseNewAjax();
} else {
UseOldAjax();
}

Later, a new version of IE comes out which supports the new features, but because you are agent-sniffing, your IE viewers can't get this feature goodness without you making a change to your code.

On the other hand, if you feature detection:

if (document.hasCoolNewAjax) {
UseNewAjax();
} else {
UseOldAjax();
}

You can be assured in the future that if a browser supports a feature they didn't before, they can start using these features immediately, and you don't have to change your code to support it.

Browser / User Agent sniffing: Using a programming language to determine what browser a visitor is using, so special logic can be written against that browser. Inefficient and considered a bad practice in the development community.

Feature detection: Using a programming language to determine whether a browser supports a particular feature. Considered a best practice in the developer community because it is fool-proof and future-proof.

From Wikipedia:

User agent sniffing is mostly considered poor practice, since it encourages browser-specific design and penalizes new browsers with unrecognized user agent identifications. Instead, the W3C recommends creating HTML markup that is standard,[citation needed] allowing correct rendering in as many browsers as possible, and to test for specific browser features rather than particular browser versions or brands.

JavaScript isn't the only language which you can user-agent sniff or feature detect from. For example, the .NET framework has properties that let you read all sorts of information about the browser:

http://msdn.microsoft.com/en-us/library/3yekbd5b.aspx

http://modernizr.com

JavaScript: Partial Feature Detection (srcset)

What is wrong with one of these polyfills:

  • https://github.com/scottjehl/picturefill
  • https://github.com/aFarkas/respimage

Or a partial polyfill like this one:

  • https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg

Detecting whether a browser supports the width descriptor is quite easy, if you have basic JS and responsive image knowledge.

Therefore, I really would suggest that you use one of the polyfills above.

var img = document.createElement('img');
var isWSupported = ('sizes' in img);

JS feature detection to detect the usage of -webkit-calc over calc

Create a dummy element, insert it in the document, use .cssText.height = 'calc(100px - 50px);', and check if the element has the expected height. Repeat this for every vendor-prefix.

Side note: For this kind of questions, you should look in the source code of Modernizr. Others have usually contributed such feature detection scripts, such as calc.js.


Modernizr detects whether the feature is present, it doesn't tell which prefix has to be used. The code below shows how to get the correct prefix:

var calc = (function(){
var dummy = document.createElement('div');
var props = ['calc', '-webkit-calc', '-moz-calc', '-o-calc'];
for (var i=0; i<props.length; ++i) {
var prop = props[i];
dummy.style.cssText = 'width:' + prop + '(1px);';
if (dummy.style.length)
return prop;
}
})();

// Usage example:
$('selector').css('height', calc + '(100% / 3)');

(I did not add the -ms- prefix, because IE started supporting it without the prefix - see http://caniuse.com/calc.)



Related Topics



Leave a reply



Submit