So far we have discussed two methods of fixing IE's rendering issues with web pages; we're about to add one more. Each method is broadly associated with the severity of issues that IE has in displaying a site:
- Low to mild problems in IE
- Typified by: a few elements displayed out of place when the page is rendered in IE, with perhaps several CSS effects not being supported; a best-case scenario that is usually gained by crafting valid code and occasional testing in IE during development.
Solution: IE CSS hacks added directly to the existing stylesheet.
- Moderate severity
- Typified by: multiple elements displayed incorrectly in IE; usually due to extensive use of CSS.
Solution: Conditional comments to introduce a limited set of IE-only CSS fixes (see below).
- High severity
- Typified by: the page being unreadable or unusable in IE, usually due to high use of CSS or HTML5.
- Solution: clean up your code and use a JavaScript shim to fix the problems IE has with your page.
Note that the appropriate solution depends upon the degree of the problem; just as a doctor should not over-prescribe antibiotics, it is a waste of resources to load in a 60K of JavaScript to fix problems that could be solved by adding just a few lines of CSS.
- Solution: clean up your code and use a JavaScript shim to fix the problems IE has with your page.
Conditional Comments
The traditional way to fix moderate IE rendering issues is to feed the browser a special "IE-only" stylesheet that contains CSS hacks or fixes. Like CSS designed for print or mobile, this stylesheet does not duplicate all the rules from the main styles.css file: it only contains the changes that are necessary for IE.
The contents of HTML comments should be ignored by the browser, but IE will actually look inside them for instructions. If the instructions are phrased as conditional statements, such as the following:
<!—[if IE]>
<link rel="stylesheet" type="text/css" href="ie.css">
<![endif]-->
(Note the spacing for the comment, which is vital to reproduce.)
… then IE will load the ie.css stylesheet and add its rules to those from styles.css. Where the rules in styles.css and ie.css conflict, IE will follow the latter. All other browsers will ignore this so-called "conditional comment", and not load ie.css. It is also possible to place embedded CSS intended only for IE between the opening and closing comment:
<!—[if IE]>
<style type="text/css">
/* IE-only styles here */
</style>
<![endif]-->
However, different versions of IE will "break" a page differently. For example, under some circumstances, a CSS fix that works for IE6 will actually break the rendering of the affected element in IE9. To get around this, it has been fairly common practice to make several IE-only stylesheets, each targeted at different versions of the browser:
<!—[if IE]>
<link rel="stylesheet" type="text/css" href="ie.css" />
/* general rules for all versions of IE, may be contradicted by rules in stylesheets that follow */
<![endif]-->
<!—[if IE 7]>
<link rel="stylesheet" type="text/css" href="ie7.css" />
<![endif]-->
<!—[if IE 8]>
<link rel="stylesheet" type="text/css" href="ie8.css" />
<![endif]-->
There are several problems with this approach: adding external files slows down page load times, and keeping track of fixes in multiple files can be very confusing. Recently, Paul Irish proposed another solution that has become popular:
<!--[if lt IE 7]> <html class="ie6"> <![endif]-->
<!--[if IE 7]> <html class="ie7"> <![endif]-->
<!--[if IE 8]> <html class="ie8"> <![endif]-->
<!--[if gte IE 8]> <html> <![endif]-->
<!--[if !IE]><!--> <html><!--<![endif]-->
This takes the unusual approach of adding a class to the html
tag. The use of the code above assumes that IE8 and higher (get
: "greater than or equal to") will work with your existing CSS. Non-IE browsers will follow the last if
condition.
By creating an HTML class for different versions of IE, you can keep your IE fixes in a single CSS file. To address IE in the main styles.css stylesheet, simply prefix declarations for different versions of IE with the appropriate class:
div#wrapper {
background-color: inherit;
}
html.ie6 div#wrapper {
background-color: #fff;
}
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.