Avoiding CSS Hacks

As many web developers know, Internet Explorer tends to be a problem when writing CSS. Despite the improvements Microsoft has made to their browser, developers will inevitably encounter some sort of unexpected result when their page is displayed.

I've tried a lot of different ways to address this issue with Internet Explorer but I haven't been happy with any of them. Conditional comments that include external stylesheets are hard to manage since you now have 6 or so files to maintain. Prefixing property names with special characters like _ or * only solves the problem in a few of the versions and then you're left with poorly written CSS.

A Clean Solution

I came across a different approach the other day and I was very impressed. It's easy to use, it doesn't require multiple CSS files or JavaScript and you can avoid messy property name hacks. Not only that, you're still able to target each of the individual Internet Explorer versions!

Let's take a look at how it works...

<html>
  <body>
    <!--[if IE]><div id="ie" ><![endif]-->
    <!--[if IE 9]><div id="ie9" ><![endif]-->
    <!--[if IE 8]><div id="ie8" ><![endif]-->
    <!--[if IE 7]><div id="ie7" ><![endif]-->
    <!--[if IE 6]><div id="ie6" ><![endif]-->

    <div class="content" >
      ...
    </div>

    <!--[if gte IE 6]></div><![endif]-->
    <!--[if IE]></div><![endif]-->
  </body>
</html>

The general idea is, instead of hacking the CSS, you use a conditional comment to wrap your page with an Internet Explorer specific element that you can use with your selectors. In this example I'm also including a generic #ie element that allows you to target any version of Internet Explorer.

Browser Detection In Action

Below is an example that doesn't use JavaScript or CSS hacks. The elements below will change their style depending on what browser you're using.

Modern Browser

Internet Explorer 6 7 8 9

The CSS for this approach is just as simple. The shows the general approach to how the correct browser box is highlighted. Some of the non-essential rules have been omitted but you can view the source of the page to see all of them.

HTML
<div class="browser-detect" >
  <div class="browser not-ie" >
    <h4>Modern Browser</h4>
  </div>
  <div class="browser ie" >
    <h4>Internet Explorer 
        <span class="ie6" >6</span>
        <span class="ie7" >7</span>
        <span class="ie8" >8</span>
        <span class="ie6" >9</span>
    </h4>
  </div>
  <div class="clear" ></div>
</div>
CSS
/* detect box default - styled as 'highlighted' */
.browser { 
  display    : block;
  color    : #fff;
  background  : #777;
}

/* default IE detect box - styled as 'disabled' */
.ie span { display : none; }
.ie { 
  color : #333; 
  background : #444;
}

/* Now, at this point we use IE id overrides to change
   which browser detect box is highlighted */

/* IE specific - styled as 'highlighted' */
#ie .ie { color  : #fff; background : #777; }
#ie .ie h4 { color : #fff; }

/* modern detect box when using IE - styled as 'disabled' */
#ie .not-ie { color : #333; background : #444; }

/* when using IE - shows the version number */
#ie6 .ie6 { display : inline; }
#ie7 .ie7 { display : inline; }
#ie8 .ie8 { display : inline; }
#ie9 .ie9 { display : inline; }

You'll notice that instead of hacks or separate stylesheets we're simply starting all of our Internet Explorer specific selectors with either #ie or one of the specific version selectors #ie6, #ie7, #ie8 or #ie9.

When a non-Internet Explorer browser displays the page the #ie selectors will not be valid because conditional elements will have been skipped. Since the none of the special wrapper elements exist the Internet Explorer specific rules will be ignored.

However, if an Internet Explorer browser visits the page, those rules will be evaluated. This will change the color of the modern browser box to the dark color and highlight Internet Explorer instead. Not only that, but the version number should be displayed as well!

So far I'm loving this approach. It is simple, easy to use and I don't feel like styles are lost when they are moved to separate CSS files.

You should always try to figure out a way to get your CSS to work correctly in all browsers before resorting to browser specific rules.

April 17, 2011

Avoiding CSS Hacks

Use conditional comments with IE specific elements to write manageable, hack free CSS.