5 Reasons Why Browser Sniffing Stinks

Tweet

Browser sniffingBrowser sniffing is the act of detecting the web browser a visitor is using in order to serve version-specific pages, scripts, images, or other content. The technique was popular around 10 years ago because Microsoft and Netscape introduced their own technologies and web standards were in their infancy. In those dark days, it was fairly common to write two or more client-side scripts to implement identical functionality in different browsers.

Fortunately, the web has progressed. There is rarely a need to fork code for different devices, but Opera’s recent experience with version 10 indicates that browser sniffing remains a commonplace technique.

Technically, browser sniffing appears to be relatively straightforward. You obtain a user agent string using navigator.userAgent in JavaScript or the HTTP_USER_AGENT environment variable on the server and parse it accordingly. However, do not be complacent; browser sniffing should not be used!

1. String parsing is tough

User agent strings do not conform to specific patterns, for example:

  • IE8: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1;
  • Firefox 3: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
  • Opera 9: Opera/9.64 (Windows NT 6.0; U; en) Presto/2.1.1

The browser, version, rendering engine, OS, language, and information about media players and .NET frameworks can all be passed in various ways. Testing every combination is impossible; Opera 10 reports version 9.8 because some sniffers mistakenly believe it’s version 1.

2. There are many browsers to handle

Ten years ago, there were only three major browsers with one or two significant versions of each. Today, there are at least five mainstream browsers all with multiple versions running on different platforms. Ensuring you only target the right browser at the right time without affecting others is not easy.

3. Reduced scalability and increased maintenance

Different sets of code for different devices is harder to maintain and can never be future-proofed. In addition, your code could break every time a new browser or version is released. That is occurring increasingly often.

4. Browser masquerading

For many years, Opera pretended to be Internet Explorer by passing that browser’s user agent. This helped Opera users visit sites which normally refused non-IE browsers. It can still be done today.

5. It’s rarely required

Web standards have made browser sniffing far less necessary on the server side, unless you happen to be implementing a browser statistics application.

JavaScript does have several cross-browser compatibility issues, but object detection is normally a better solution. For example, IE7 and below do not have native support for XMLHttpRequest, the object essential for Ajax requests. However, an identical ActiveX object can be used instead – most libraries implement code such as:


var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));

A possible exception could be progressive enhancement aimed at specific browsers. For example, to support 24-bit PNGs in IE5.5 and IE6, browser sniffing could be used so images are only replaced if necessary. However, that is a workaround which will ultimately be removed once people stop using those browsers.

Cross-browser CSS is also possible – yes, even in IE6. Conditional stylesheets can help in extreme cases, although I personally avoid them because it still feels too much like browser sniffing!

See also: Why Opera 10’s User Agent Smells Bad

Do you avoid browser sniffing? Are there any situations when it’s essential?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • chrisrikli

    “1. String parsing is tough”
    Only if you can’t write the most basic of regular expressions.

    The rest is solid though. Javascript libraries like mootools/jquery/prototype/scriptaculous make it way to easy to write cross-browser compliant code. If you’re not using one of these libraries you’re wasting a ton of valuable development time.

    My approach to the whole browser issue (in other words, “Ok, it works on everything else but IE”) is to use a conditional comment that wraps the entire page in a div, as follows:
    <body>
    <!–[if IE]><div id=”IEsux”><![endif]–>
    blah blah blah
    <!–[if IE]></div><![endif]–>
    </body>

  • http://www.optimalworks.net/ Craig Buckler

    It’s not the regex’s that are the problem, but the difficulty in parsing the string and extracting useful information such as the version number.

    Just when you think you’ve cracked it, someone comes along with an unusual user agent that breaks your code. The plethora of information about media players and .NET frameworks doesn’t help either. Seriously, try it out. Even jQuery’s browser sniffing is deprecated and will report Chrome and QtWeb as Safari.

  • http://www.olsenportfolio.com/ nrg_alpha

    I am in complete agreement that browser sniffing isn’t recommended (although I am guilty as charged for doing so – but in future web projects, will not be making use of it), I don’t find parsing the user agent difficult at all. In all cases, I have to check for IE (as we all know how well IE plays along with w3c standards!). So with some simple regex (and knowing what to look for), I can easily detect whether it is IE, or an older version of Opera and go from there…

    When people only detect the first digit in the version, this is where they get snagged when browsers hit version 10.x. Just comes down to bad regex / string parsing methodologies IMO. But again, I’m in agreement with avoiding this practice altogether and I will not adhere to it in future websites I make.

    Someone once posted this:
    http://webaim.org/blog/user-agent-string-history/

    Quite a nice little history about user agents.

  • http://blog.afterlight.net.au AussieJohn

    I’ve found, that the more JavaScript I write, the less code I write specifically for browsers, when I have done in the past, it has been only to tackle a few issues in IE6. Of course using a framework helps a lot as well. I’m a big fan of just writing code and letting the framework taking care of all the browser inconsistencies. I particularly like that feature detection is used rather than straight out version sniffing.

  • nedlud

    We have an antique CMS, the inline editor for which claims to only work in IE6. In practice we have found that it also works in IE7 (but only IE). We also just foud that it doesn’t work in IE8 (even in compatability mode) :(
    It’s a comercial product that we don’t have permission to “fix”, so until we upgrade the entire CMS product, we are stuck detecting browsers and only letting people log in if they have IE6 or 7.

  • http://www.dangrossman.info Dan Grossman

    Gary Keith has maintained a database of user agent regular expressions and browser capabilities for many years. It’s kept up to date and support is built into PHP (get_browser).

    http://browsers.garykeith.com/downloads.asp

  • http://blog.afterlight.net.au AussieJohn

    @Dan: The point is that Browser sniffing is a bad practice

  • http://www.dangrossman.info Dan Grossman

    @AussieJohn: Well, that depends what you’re doing the sniffing for, doesn’t it? If your goal is to compile statistics on what browsers are visiting your site so that you can make intelligent decisions about feature support and degredation, wouldn’t it make perfect sense to do user agent browser sniffing with a database like that?

  • http://blog.afterlight.net.au AussieJohn

    @Dan: Apologies, you are correct of course – there is is definitely room for user agent detection, where indeed would we otherwise get our lovely statistics from :-)

    I was talking more about the client side of things of course, (which is what the article is about, really).

    Browser sniffing is the act of detecting the web browser a visitor is using in order to serve version-specific pages, scripts, images, or other content.

  • http://www.dangrossman.info Dan Grossman

    Agreed :)

    There’s not much other reason to do sniffing these days. I come across more sites using JavaScript libraries to do AJAX and other client-side stuff more often than entirely custom code, and the libraries do the work of figuring out what the browser supports.

    IE6 is the only browser I still have to write a conditional stylesheet for.

  • Anonymous

    Browser sniffing may stink but it’s the reality. For instance, server-side sniffing of the user-agent may be the only way to properly serve mobile/handheld content, since they almost never use sensible CSS media type settings.

    Similarly, but very rarely, a Javascript bug will cause the browser to crash when even attempting capability testing – as such version-sniffing may be the only reasonable workaround.. but this is obviously a last resort.

  • Philip John

    It strikes me that the attention is in the wrong place here. Web developers have to browser sniff to combat the difference in browser implementation of W3C standards to make sure their visitors don’t have a bad user experience.

    Rather than telling developers to stop it, focus on eliminating the need for developers to sniff.

    Make efforts towards a standardised format for the user-agent string, for example. I’m sure web developers every where would rather not sniff, but they have been forced to.

  • James

    Seems like none of you have ever tried developing sites for mobile devices.

    Hold tight.

  • Jangly Mark

    You have to do a bit of browser sniffing becuse of ONE browser…I also give users a message…

    My code is as follows :

    If you are using Internet Explorer 6, this page may not display properly.
    For a better web experience, download FIREFOX for FREE here

  • Anonymous

    Sorry for the double post, I only saw the bit about code samples as I pressed ‘Submit’.

    I still have to do a bit of sniffing because of you know who…I also give users a message…

    Code is as follows :

    <!–[if IE 6]gt;
    <pgt;</pgt;
    <pgt;<font size=+2 face=”Impact”gt;<bgt;If you are using Internet Explorer 6, this page may not display properly.
    For a better web experience, download FIREFOX for FREE <a href=”http://www.mozilla-europe.org/en/firefox/”gt;here</agt;</fontgt;</bgt;</pgt;
    <pgt;</pgt;
    <![endif]–gt;

  • http://blog.afterlight.net.au AussieJohn

    @Phillip John: I agree – life would be easier if browsers would actually adhere to standards

    @James: I have worked in Mobile web dev, all our sniffing was done on the server side though. Ultimately, we tried to do capability sniffing to determine whether to show WML or XHTML pages (this was when WURFL was still in it’s infancy). I’m sure you agree that developing for mobile devices can be (and usually is) more of a pain than the handful of PC/Mac browsers.

  • Hamranhansenhansen

    I disagree that there are no reasons to sniff. There are 4 major incompatible versions of IE out there, 5 thru 8, and they are incompatible with everything else also. Sniffing for “MSIE” is very reliable, and even the versions are done in the same way from IE 4-8 so you can reliably tell them apart. And a browser that is not IE but sends “MSIE” is specifically asking you to treat it as IE and you should respect that by doing so. Second-guessing it and trying to treat it as Opera or whatever is not appropriate.

    However, I agree you should not sniff on the client side, that is way too kludgey. CSS hacks and conditional comments are like a sign that says “we don’t know server-side scripting here” or else you would have done it with a simple if then else in PHP or any other language. Why even send the client code that it can’t parse?

    For example, you can sniff MSIE with PHP and return one <head> tag if so, and a different <head> tag if not, each linking to different styles and scripts. Or, you can return the same <head> tag to all browsers, but if you find MSIE, you add an extra stylesheet with the IE-specific crap in it.

    Another advantage to doing this on the server is you can change it later easily. For example, once IE is down to <20% of the Web in a couple of years (because the Windows PC’s that it requires are down to <25% of the Web by then) you may decide to stop specifically working around its many problems. In that case, you can remove the browser sniff at the top of your server-side code very easily and from then on, you only return the standardized code that you already know was working in other browsers.

  • Hamranhansenhansen

    > Seems like none of you have ever tried developing
    > sites for mobile devices.
    >
    > Hold tight.

    Mobile is 98% WebKit by usage. Google has a couple of apps that run better on the iPhone than the desktop because they don’t have to support MSIE.

    Once the feature phones go to WebKit, IE will be only a small percentage of the Web, and it will still be split into various incompatible versions. We probably won’t bother sniffing for it.

  • DStorey

    > Mobile is 98% WebKit by usage.

    And 80% of statistics are made up on the spot. See http://www.reuters.com/article/marketsNews/idUSL224684120090602 for a source which shows that to not be true.

  • dstorey

    > Mobile is 98% WebKit by usage

    And 80% of stats are made up on the spot. StatCounter would beg to differ on that stat, where Opera is the biggest mobile browser – http://www.reuters.com/article/marketsNews/idUSL224684120090602

  • http://blog.afterlight.net.au AussieJohn

    @Dstorey:

    I wanted to look up the amount of statistics actually made up on the spot, since yours was clearly made up, on the spot.
    Unfortunately a quick google search only resulted in more made up statistics.
    http://www.google.com.au/search?q=how+much+statistics+are+made+up+on+the+spot
    ;)