Confessions of a browser sniffer

October 16, 2002

On a personal site I am developing, I started out with the intention of working just with standards.

There would be no browser-specific code at all. Not for MSIE, not for Opera, and definitely not for Netscape4.

A few days went by and my resolve weakened… I cheated. Just a little bit. I can stop whenever I want to. Really.

What followed what a short course in why we need to follow standards, and why those who ignore web history are doomed to repeat it.

The idea was pretty simple.

It’s a personal site. I use standards-supporting browsers (Opera and Mozilla). Make it strict. As strict as it can be.

At first I was just thinking about CSS really. I had grown tired of the ever growing list of browser specific hacks (including ones for Opera).

“The next time I build a site, I’m going to forget all this hackery and just do it like it is supposed to be done,” I said to myself in the luxury of knowing this would be a largely personal venture, not some client I wanted to hire me.

Then there was a comment about using application/xhtml+xml [see previous entries], and I decided that I wanted to use that.

It took mere seconds to run into the first bump in the road. MSIE provided the bump, as it does quite often. MSIE can’t handle application/xhtml+xml or any other XHTML MIME type. Some it wants to display as source. Others it wants to download.

I was a little happy. I had something that MSIE couldn’t handle that Moz and Opera could. Yet more fodder for the “MSIE is crap” file.

But then I realized something.

If MSIE couldn’t handle it, that was actually OK. I didn’t mind that, except that the site, although personal, was something I was hoping would turn into a resource for others. Three problems then:

1) if MSIE couldn’t handle it, people who wanted to learn wouldn’t be able to access the site if they were using that browser.

2) Search engines probably wouldn’t be able to index the site.

3) It would be inaccessible to folks using Lynx (and I assumed it would also be inaccessible to others using assistive technologies

Of the 3, only the last two really bothered me, but I decided I needed to do something.

I could use the HTTP_ACCEPT header, and send XHTML to browsers that said they could handle it, and send HTML to the others. I could do that using Apache, if I understood Content Negotiation (which I didn’t, and still don’t).

Or I could take the easy way out. I could cheat. It would be a good cheat after all.

I knew that Mozilla based browsers (Phoenix, Moz, Netscape 6+ and others) all used the word ‘Gecko’ in the User Agent string.

Likewise, I knew that Opera uses the word ‘Opera’ in the User Agent string.

This would be an easy solution.

Now I have to confess that I should have known better. I knew, and had even recently written about the evils of browser sniffing and the problems it has caused.

But I can handle it. I know what I’m doing.

After all, I already knew that the browsers I was testing could handle what I wanted to send them. And the other browsers would get content suitable for them. What could go wrong?

I tried my best to ignore the little cracks in the glass.

I was sniffing for ‘Opera’ but what about older versions of Opera? Could they handle it? (tough nuts, I said, it’s their fault for using an old browser… then I went and tested Opera 5.12 [which did OK] and even tracked down a copy of Opera4 [which tried to save it, understandable])

What if someone changed their UA string? (too bad, I said, they knew the risks.)

But then it hit me. Hard. Like a slushball on a cold winter day against that tiny bit of exposed skin between your scarf and your hat.

What about other browsers that can handle application/xhtml+xml that I don’t know about? What happens when Internet Explorer 7 comes out and can handle application/xhtml+xml? Wasn’t I about to do exactly what I hated? What so many others had done before that caused the whole terrible situation we found ourselves in for HTML and CSS and Javascript and all the others?

My feeble attempts at arguments had failed. When you can’t even convince yourself, you pretty much have to admit you’re wrong.

I hate it when that happens.

The standards way of doing it would be to use the HTTP_ACCEPT header. That’s what it is for. I had spent all of this time trying to avoid using it because I didn’t know how, and it was easier to use the User Agent string. I felt dirty. Worse, I felt hypocritical.

Fortunately I had found that PHP could access the HTTP_ACCEPT string just as easily as the User Agent string. A little bit of PHP and voila, it worked.

Sort of.

Opera, it turns out, doesn’t list application/xhtml+xml in its HTTP_ACCEPT. I wanted to cry. I could use Mozilla, but I like Opera much better. So I compromised and sniffed for any browser that said it could handle application/xhtml+xml OR any browser that said it was Opera.

But what about older versions of Opera?

The heck with it. I adapted the PHP code again to only even think about application/xhtml+xml if the browser was coming from my home IP.

So the PHP read:

0) If the IP matches my home IP, then

1) If the browser says it can handle application/xhtml+xml then give it. This would handle any new browsers that might come along.

2) elseif the browser says it is Opera then give it application/xhtml+xml

3) else, give text/html

Perfect. My little test case worked fine. I put the script into effect on the rest of that site.

And Opera immediately stopped showing my CSS.

My little test case didn’t have any CSS. After all, it was only a little test case.

I went around and found the answer on Google. An obscure little bug in Opera 6 dealing with application/xhtml+xml and linked CSS files. There was a workaround.

I spent about 30 minutes banging out a hack that would fix it in Opera 6.05 before I said “Enough.” It wasn’t working, and I was spending all of this time on a browser specific bug to use a feature that the browser itself did not advise (hence the absence of application/xhtml+xml from the HTTP_ACCEPT).

So I gave up on Opera 6.05 and hoped Opera7 would fix the bug and list application/xhtml+xml in the HTTP_ACCEPT.

I removed the code that looked for Opera at all, and cut the script down to just look for my home IP (for now) and application/xhtml+xml in the HTTP_ACCEPT.

After several hours, I had come back to using the standards for the purposes for which they were intended, mumbling incoherently and realizing that instead of spending the evening learning something new (which was the purpose of this new ‘strict’ site) I had wasted the entire night learning something old.

Browser sniffing (aka UA sniffing) is bad. Browser sniffing is a waste of time. Browser sniffing is far too imprecise. Browser sniffing means less time spent on actual content and more time spent on administration (and who needs more administration in their life?) Browser sniffing may work today, but you will have to come back tomorrow to make sure something hasn’t changed (new release of MSIE or some other browser, new obscure bug in old browser that you formerly thought you could accept, etc)

Standards are good. Standards save you time. Standards let you be precise and it’s up to the software to work properly. Standards mean more time creating and less time maintaining. Standards let you write today and have it work tomorrow, probably to an even wider audience than you have today.

I learned what I already knew, but I shan’t forget it again.

  • Yeah, I've seen Opera's Accept: header too and wondered why it didn't send the XHTML MIME types. I didn't know about the bug. Thanks for the scoop!


    You can actually feel the agony in your writing. :-)

  • Am I the only one who finds application/xhtml+xml to be a horrible mimetype? Was text/xhtml really too much of a stretch?

  • millind

    Can someone let me know what are the precautions to be taken for building the webpage for Opera.


    Moslty we do this for netscape and IE.


    Foreg. marginwitdh marginheight etc.

blog comments powered by Disqus

Previous post: HTTP_ACCEPT and opera.ini

Next post: Meanwhile, MS is ‘innovating’ disinformation