Targeted CSS and JavaScript for Document States, JavaScript Support, and Internet Explorer's Versions

By Ryan Florence, published 2010-04-09

Part of the issue Migrated Articles From Original Site Structure..

There are differing opinions on how to support Internet Explorer in all it’s flavors. I’m the type that makes the site look and act the same in every browser as similarly as possible most of the time. I use modernizr to help me know when I can use CSS instead of images or whatever else–but that’s not always enough for IE. For example, it supports background gradients, just not CSS gradients. Here’s a trick Thomas Aylott @subtlgradient came up with that we used recently on a site we developed together. It has proven very helpful–plus, it’s framework independent.

Here’s the gist, if you want to use this technique. Continue on for some details.

<!DOCTYPE html>
<html class=no-js>
<head>
        <meta http-equiv=Content-Type content="text/html; charset=UTF-8">

        <script>(function(){try{
                var className = 'js loading not-ready';
                className += top === window ? ' not-framed' : ' framed';
                document.documentElement.className = className;
                this.navigator = this.navigator || {};
                this.navigator.isIE = NaN;
        }catch(e){}})();</script>
    
        <!--[if !IE]>--><script>try{document.documentElement.className+=' not-ie'}catch(e){};navigator.isIE=NaN</script><!-- <![endif]-->
        <!--[if lt IE 6]>  <script>try{document.documentElement.className+=' ie5'}catch(e){};navigator.isIE=5</script><![endif]-->
        <!--[if IE 6]>     <script>try{document.documentElement.className+=' ie6'}catch(e){};navigator.isIE=6</script><![endif]-->
        <!--[if IE 7]>     <script>try{document.documentElement.className+=' ie7'}catch(e){};navigator.isIE=7</script><![endif]-->
        <!--[if IE 8]>     <script>try{document.documentElement.className+=' ie8'}catch(e){};navigator.isIE=8</script><![endif]-->
        <!--[if gte IE 9]> <script>try{document.documentElement.className+=' ie9'}catch(e){};navigator.isIE=9</script><![endif]-->
</head>
<body>
...

Then add this somewhere if you’re using MooTools:

// Swap classes onload and domready
document.addEvent('domready',function(){ $$('html').removeClass('not-ready').addClass('ready'); });
document.addEvent('load',function(){ $$('html').removeClass('loading').addClass('loaded'); }); 

And for jQuery:

// Swap classes onload and domready
$(function(){ $('html').removeClass('not-ready').addClass('ready'); }); // jQuery
$(window).load(function(){ $('html').removeClass('loading').addClass('loaded'); });

What it does for CSS

The html tag gets one of these class names:

Now, instead of having to include a separate stylesheet, you can target specific css to internet explorer’s versions in your regular stylesheet, or set styles for specific document states and javascript support like this:

li { margin-top: 10px; }
.ie7 li { margin-top: 11px; }
.ie5 li, .ie6 li { margin-top: 100px; }
/* Stays visible is JS is disabled */
.js .lazy-loaded-widget {display:none}
/* Fade in on domready */
.widget { -webkit-transition: opacity 0.5s ease-in }
.not-ready .widget { opacity:0 }

No more screen-ie6.css for you!

What it does for JavaScript

The navigator.isIE gets a value of:

Therefore, you can do stuff like:

// target a specific version
if (navigator.isIE == 6){
  // do stuff for IE6
};

// Deliever different behaviour for a group of IE versions
if (navigator.isIE < 9){
  // ie's notorious png-tranparent-pixels-go-black-on-fade issue
  $('png-image').setStyle('display','none');
} else {
  $('png-image').fade('out');
};

// Check for IE generally
if (navigator.isIE){
  // do IE stuff
} else {
  // do other stuff since NaN is falsey
};

Conclusion

One of my favorite feelings is popping open my Windows XP virtual machine, running the wonderful IETester, and then seeing my finished site working nearly identically in all browsers. It is strange to relate that all of the IE versions are as different, or even more different, from each other than Safari, Firefox, Chrome, Opera and all their versions put together. It’s like a bunch of cousins looking like quadruplets and then some off-siblings kids all looking vastly different from each other and their look-alike cousins.

Technical pedantic nerd note: This browser detection uses 0 User Agent sniffs. This uses a proprietary feature of IE browsers to allow them to identify themselves as a specific version of IE. This is completely safe in all known browsers and doesn’t even throw errors on unique browsers such as the PS3 embedded NetFront browser (for full PS3 support you need to replace document.documentElement with document.getElementsByTagName('html')[0]). If you do find any bugs, please let us know.

Hi, I'm Ryan!

Location:
South Jordan, UT
Github:
rpflorence
Twitter:
ryanflorence
Freenode:
rpflo

About Me

I'm a front-end web developer from Salt Lake City, Utah and have been creating websites since the early 90's. I like making awesome user experiences and leaving behind maintainable code. I'm active in the JavaScript community writing plugins, contributing to popular JavaScript libraries, speaking at conferences & meet-ups, and writing about it on the web. I work as the JavaScript guy at Instructure.