April 6th in Articles, JavaScript by .

Conditional Classes And Browser Version Detection


For a long time now, web developers have searched for and used a variety of techniques to target styles to specific browsers and browser versions to fix incorrect implementations of web standards or simply bugs. The biggest culprit of the bunch is our good friend Internet Explorer.

As developers we have moved on from the various style sheet hacks such as * and _ and embraced conditional comments to target specific versions of IE. While this works, it does add an extra HTTP request and forces the developer to manage the same styles in different files, not an ideal situation.

A while back Paul Irish published an article entitled “Conditional stylesheets vs CSS hacks? Answer: Neither!“. Through the initial concept posted by Paul and the follow up comments by Mat Marquis (@wilto) and Rob Larsen (@robreact) we now have a new solution with some handy side effects which is also part of the HTML5 Boilerplate. This is what the code looks like:

<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7 ]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]>    <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]>    <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

That’s it, no loading or managing of different CSS files for each version of the browser targeting, for example IE6 is as simple as this:

.ie6 #container {
    zoom:1;
}

Now, one of the really useful side effects of this is aiding you in targeting different versions of Internet Explorer in your JavaScript without the need for browser sniffing. Before you click back or leave a nasty comment, I know we have moved on from browser sniffing and the de-facto way is to use feature detection, however, finding that one feature that is only supported in IE6 but not IE7 or 8 and so forth can be next to impossible.

Falling back to browser sniffing might be an option but, with the above code in place there is no need. What I am hinting at here is to make use of the classes set on the <html> tag. Say you decided that you are ending support for IE6, and please we need to do this, but do not want to leave the users high and dry with a completely broken interface. You might want to hide some of the widgets that will not work in IE6 and show the user a message encouraging them to upgrade their browser.

Using jQuery, this can be accomplished as follows:

$().ready(function() {
    if($("html").hasClass("ie6")) {
        $("#widget").hide();
        $("#upgrade").show();
    }
});

Very simple and effective. But what if you do not have jQuery on the page? Not a problem, if we examine the jQuery source and look at the hasClass function, we can grab the source, and with one minor change still be able to make use of our conditional classes:

var rclass = /[\n\t\r]/g;
var hasClass = function(ctx, selector) {
	var className = " " + selector + " ";
	for ( var i = 0, l = ctx.length; i < l; i++ ) {
		if ( (" " + ctx[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
			return true;
		}
	}

	return false;
}

window.onload = function() {

	var htmlTag = document.getElementsByTagName("html");

	if(hasClass(htmlTag, "ie6")) {
        document.getElementById("widget").style.display = "none";
        document.getElementById("upgrade").style.display = "block";
    }
}

With the above you are now set-up to target any version of IE you need to support using the conditional classes in your CSS and the hasClass method in your JavaScript. Looking forward to your comments.

Image courtesy Pedro Moura Pinheiro

  • http://paulirish.com Paul Irish

    Lets make this whole thing require no javascript at all!

    .ie6 #widget { display: none; }
    .ie6 #upgrade { display: block; }

    • Anonymous

      Hey Paul, in this use case that will definitely be the better approach, maybe not the best example ever ;) But there are certainly times when you need to target your script at a specific version of IE and the values, maybe calculated heights and widths, are not known before hand and you therefore need to use JavaScript.

      Thanks for your comment.

    • http://emwendelin.myopenid.com/ Eric Wendelin

      Good call, Paul. Down with unnecessary javascript!

      • Anonymous

        Dang it, I am going to have to change this example. I agree that the current example can be accomplished with no JavaScript and it would be better. bad me

Performance Optimization WordPress Plugins by W3 EDGE