Developing CSS for IE6 and 7

Posted on 09 March 2009 by Rachel Andrew


Browsers these days are actually pretty good. Most of the time, if I have built and validated something and it works in Firefox, I can be pretty sure that when I do my testing in the latest versions of Opera, Safari, Konqueror and yes even IE8, everything will be fine. This is what we asked for, back in the early days of the web standards movement, and I do think we are getting to that point.

If modern browsers tend to deliver a consistent experience when presented with valid, sane CSS and (X)HTML this only makes more frustrating the sight that we are presented with in older versions of Internet Explorer – version 6 more so than 7, although both have their issues.

As someone who does a fair bit of non-trivial CSS development (you can see some examples of front end development in our Case Studies) I thought I would share my practical tips for dealing with IE.old.

Develop using an up to date browser

You should develop your layout initially in a browser that complies to the CSS specification well. Browsers are becoming more standards compliant, not less. So you want to ensure that the CSS you write today complies with the spec as it is then most likely to behave in as yet unreleased browsers.

I never look at the layout in Internet Explorer while building it. If I do I might be tempted to start hacking at my mark-up or adding in unnecessary elements in my CSS. I want to get things right in browsers that behave first before worrying about those that don’t.

Validate mark-up and CSS

Once I have my layout looking right in my browser of choice I go to the validator and check that both CSS and mark-up are correct.

Check in other modern browsers

I now have a look in other modern browsers – Firefox, Opera, Safari and Internet Explorer 8. I very rarely need to make any changes to my work at this point. When I have needed to make changes it has usually been a simple adjustment of approach to make something work. I don’t expect to add hacks or alternate stylesheets for these browsers.

It would be worth mentioning at this point that one reason we have few problems in modern browsers, in addition to the browsers just being a lot closer to the specifications in their CSS support, is that we develop in a very robust way. We expect that data will be coming from a content management system rather than being carefully placed in by hand and so will use the odd redundant div in the mark-up if it ensures things clear properly or that padding will be properly applied and so on. This may upset the purists but I live in a real world of deadlines, content that is often out of our control and limited budgets.

Take a deep breath and launch IE6

At this point you know your CSS is valid and works in up to date browsers, so from this point on anything that is a problem in an old browser you can fix using appropriate methods for that old browser. I believe strongly that you should not clutter your mark-up or CSS with bug fixes for ancient browsers.

There will probably be some problems in IE6 when you first look at your layout. These might just be small problems such as the padding between page elements looking a bit off or may include huge sections of your page disappearing or displaying in an odd place. Do not panic! Most IE6 issues can be easily resolved by sending some different rules to this particular browser.

Choose your weapon

Before doing anything else you need to decide how to send your different rules to IE6. There are two methods of doing this, “hacks” or Conditional Comments. When we refer to hacks in CSS what we are describing is the use of some bug in a browser’s implementation to allow us to send CSS to it to deal with another bug. Where IE6 is concerned the most useful hack is the * html hack.

  • html

Internet Explorer 6 only will parse a CSS rule that starts with * html. This doesn’t really make any sense and so other browsers ignore the rule, so this can be used to serve specific CSS to Internet Explorer 6 only. Internet Explorer correctly interprets this and so also ignore the CSS. As a simple example, IE6 treats the property height as if it were min-height, so we might do:

.box { min-height: 50px; }

  • html .box { height: 50px; }

All modern browsers will interpret the first rule, and give the box a minimum height of 50 pixels. IE6 will then also parse the second rule which will overwrite the first and so it will give the box a height (which it treats like min-height) of 50 pixels.

Hacks or filters do have a bit of a bad press these days, mainly because with modern browsers you really shouldn’t need to use them. However I think this is a legitimate way to target IE6 especially if you only have a few things to fix. I would suggest however that you put your fixes into a separate stylesheet rather than leaving them inline. Just make sure that stylesheet comes after the main stylesheet in the source so the rules overwrite the existing ones.

Conditional Comments

The second way to target old versions of IE is to use Conditional Comments. I have to admit to being made slightly uneasy by Conditional Comments. The comments in HTML are not supposed to be parsed and here we have an example of a browser manufacturer putting proprietary information into them.That said, they offer a handy way to deal with issues in both IE6 and 7, and mean we can keep our browser specific CSS neatly in separate files. I think they are the best thing we have to deal with the broken CSS is IE6 and 7 and would suggest you use them unless you really do only have a couple of tweaks to make for IE6.

Conditional Comments are the use of the standard HTML Comment, with special mark-up added that is understood by Internet Explorer browsers. So if you want to load in a stylesheet only for IE6 you could use the following:

Or for IE7:

Or, perhaps your problems exist both in IE6 and 7 and you want to use the same stylesheet for both. In this case you can use a comment that targets IE versions less than 8.

If you have discovered issues in IE6 my suggestion would be that at this stage you create a new stylesheet ie6.css and add if after your existing stylesheet(s) using a conditional comment.

Fixing the problems

So now you have a stylesheet that is only going to be seen by IE6. As this comes after your other stylesheets any selectors you use in this stylesheet will overwrite those used in your all browsers stylesheet, so you can now start to tackle the issues. I’m going to list here the most common solutions to IE6 weirdness in the order that I try them – it isn’t an exhaustive list but check the links at the end of the article if these tips haven’t helped.

Check your DOCTYPE

IE6 (in common with other modern browsers) can display web pages in 2 modes – standards and quirks. Quirks mode essentially displays your layout as if you were using a really old browsers such as IE5 that had a broken implementation of the Box Model. If you are developing a new site this is not something that you want!

Quirks Mode is triggered by using no DOCTYPE, an old DOCTYPE (such as HTML3.2) or a broken DOCTYPE. In IE6 it is also triggered if you have anything else above the DOCTYPE. Before you do anything with IE6 make sure you have a full HTML or XHTML DOCTYPE, including the URL, and there is nothing above it in the source – such as comments.

Setting height to 1% – triggering hasLayout

IE6 and IE7 have a mysterious property called hasLayout that is the source of many seemingly bizarre rendering bugs. There is an excellent explanation of hasLayout in the Sitepoint CSS Reference and if you don’t know about hasLayout reading up on this property is probably the single most important thing you can do right now. In short, when an element is said to have layout it is responsible for sizing and positioning itself. If your element does no have layout then this is where you get all kinds of weird things occurring such as the contents of a div disappearing.

In IE6 I find the simplest way to trigger hasLayout on an element is to give it a height of 1%. As we discussed earlier, IE6 treats height as min-height, so a height of 1% actually renders as a minimum height of 1% so this is perfectly safe to apply and will not cause the box to be too small for it’s contents. Obviously you need to do this in your IE6 specific stylesheet as browsers that apply height correctly will make your boxes too small for their contents.

It isn’t always immediately apparent which element is going to need the height applied, but if you work methodically you may well find the one that causes everything to jump into shape. I usually work from the innermost container out, so if I have a div nested inside 2 more divs I would add the height to the inner div and refresh to see if it made a difference. If not I would remove it and try the next div and so on.

Adding position: relative

If adding a height to trigger hasLayout does not work sometimes setting position: relative on an element will cause IE6 to behave. Unless you have a child element that is taking it’s positioning context from a parent element of the element you set position relative on this should be a safe thing to do.

Using brute force

The above tips should fix the worst IE6 issues. You may still however be left with things being slightly out of line, or having incorrect margin or padding. At this point remind yourself that what you are dealing with is a buggy, old browser and you should feel quite at liberty, in your IE6 specific stylesheet to pull elements around by changing the margin and padding or positioning properties until it does work. This won’t effect any other browser as your stylesheet is only for IE6 so no harm is done. Hopefully you won’t have to do too much of this because obviously this will need to be redone if the layout ever changes, but sometimes with a very complex layout you do need to just hammer things into place!

Internet Explorer 7

Some of the above issues – in particular hasLayout – do exist in IE7 and so you can repeat the process for that browser if required using another stylesheet added with conditional comments. I usually find that I don’t need all of the rules used for IE6 but sometimes some of them are still required to get IE7 to behave. It is rare that I find a brand new issue in IE7 that I didn’t already see in IE6 ad the fixes are generally the same.

Dealing with lack of support for CSS

I’ve been mainly talking about dealing with bugs in this article. Another place where IE6 may frustrate you is the lack of support for parts of the CSS specification. For example the lack of :hover on elements other than anchors. Depending on the likely users of the site you are building this may be a case for not providing the full experience of the design to IE6. For example in modern browsers your table rows highlight when the mouse is held over them but in IE6 this does not happen. This will not make the site unusable in IE6 but is an extra nice touch for modern browser users.

Another option is to use JavaScript to plug the holes in CSS. In the above example of table row hover you could use JavaScript to dynamically add a class to the row to make the hover effect show in IE6. I find that the jQuery library which has support for CSS selectors (including CSS3) is excellent or adding these kind of touches and it is very easy to get started with jQuery for this kind of troubleshooting even if you are new to JavaScript. Do remember to only use JavaScript to add these kind of touches and not to force a layout to work – in the event of an IE6 user coming to the site who doesn’t have JavaScript enabled you want to ensure that everything still works even if it doesn’t look as pretty.

Wrapping up

This article explains what we do when getting layouts to work in Internet Explorer.

  1. Build for our most up to date standards compliant browser
  2. Validate the mark-up and CSS
  3. Test in other modern browsers and make necessary fixes
  4. Test in IE6
  5. Add a stylesheet for IE6 using Conditional Comments after the existing stylesheet
  6. Use our knowledge of likely IE6 issues to fix any problems and then use brute force if necessary
  7. Repeat for IE7
  8. If additional styling is required using CSS that is unsupported in IE6 and 7 decide whether we can just leave it for those browsers or whether to use jQuery to plug the holes and enable support

Taking a methodical approach and not allowing IE6 to change the way we build sites for modern browsers means we manage to create even the most complex layouts and get them working in IE6. As time goes by I expect that we will begin to serve more simple layouts to IE6 as it will not be cost effective to spend the time testing and tweaking for a very small minority. However there is no reason that, while there are people still using IE6, a site should be unusable in the browser.