President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William's background in scientific computing and education from Shippensburg and MIT provided the foundation for MarketingCloudFX and other key research and development projects at WebFX.

For years, Internet Explorer 6 (IE6) has been the bane of existence for web designers around the world. Designers and users alike have come to enjoy the increasingly predictable, standards-compliant behavior of great modern browsers like Firefox, Opera, and Safari. Meanwhile, IE6 continues to haunt our designs, lurking in dark places as its reputation dies and it dies a painfully slow, agonizing death. As we await that grand and glorious day when IE6 is as dead as Netscape 4, let us be mindful of the endangered species of users who, for whatever sad reason, continue to torture themselves with that terrible beast of a browser.

So come now, let us celebrate these last days of IE6 with this definitive guide to taming the IE6 beast.

In this comprehensive article, you’ll learn some of the best methods for supporting IE6, including proper targeting, specific hacks, image support, box models, floats, and everything in between.

Use conditional comments to target IE6

Conditional comments play an important role in getting IE6 to behave. Conditional comments are basically snippets of code that are included in your (X)HTML markup that enable you to target or filter specific versions of Internet Explorer. Here is a conditional comment that targets IE6 with a special message:

<!--[if IE6]> <p>Oops! Looks like you're still using Internet Explorer 6! You deserve better!</p> <![endif]-->

This is an extremely useful method of delivering code and content only to IE6. Other browsers will see this conditional comment as an ordinary (X)HTML comment and simply ignore its contents. Thus, when adapting our web pages for IE6, conditional comments enable us to apply CSS styles directly, without interfering with other browsers. Although conditional comments are a proprietary Microsoft invention, they are arguably the best way to “hack” specific versions of Internet Explorer.

The easiest way to use conditional comments to target and apply styles only to IE6 is to include an “IE6-only” stylesheet in the <head> section of your web pages:

<!--[if IE6]> <link rel="stylesheet" href="http://domain.tld/ie6.css" media="screen" /> <![endif]-->

Then, in the ie6.css stylesheet, we place all of the IE6-specific hacks and other trickery that are needed in order to accomodate IE6. This enables us to consolidate our IE6 styles into a single stylesheet that is completely ignored by all other browsers. With this method of applying styles to IE6, there is no need for IE6-specific hacks such as the so-called “star-HTML” hack or the underscore hack. Selectors are simply targeted “as-is” from within the IE6-only stylesheet.

Of course, conditional comments can do much more than target IE6. By design, they are able to target or filter any version(s) of Internet Explorer for both HTML and XHTML. For more information on conditional comments, these fine articles are highly recommended:

Target and filter IE6 with “in-CSS” hacks

Despite the usefulness of conditional comments, there are situations in which you may decide to apply IE6-specific styles from within the stylesheet. A good example of this may happen during site development, when it is more expedient and practical to work with a single stylesheet, in which IE6 styles are located next to “normal” styles for easy comparison. Once development is complete, all “in-CSS” hacks may be consolidated to an IE6 stylesheet included via conditional comments.

Fortunately, when it comes to IE6, there is no shortage of these in-CSS targeting methods. Over the years, a few of these “hacks” have risen to the top of the pile, proving to be extremely useful and effective for targeting IE6. Perhaps the most widely used of these in-CSS techniques is known as the “star-HTML” hack:

/* target IE6 */* html #selector { color: red; }

While standards-compliant browsers ignore this illogical selector, IE6 treats it as legitimate, even though <html> is the highest element in the document tree. This enables us to apply CSS styles exclusively to IE6 without interfering with other browsers. Best of all, this method of targeting IE6 is completely valid.

There are also cases where we need to hide styles from IE6. The following hack is referred to as the “child-selector filter,” and it enables us to apply CSS styles to all browsers except IE6:

/* filter IE6 */html>body #selector { color: red; }

This selector is also completely valid, and readily applied by all standards-compliant browsers. It is effective because IE6 simply doesn’t understand its meaning.

Other useful methods of targeting and filtering IE6 include the !important hack, which is useful when you need to override a property value for IE6:

#selector { width: 200px !important; /* target other browsers */ width: 100px; /* target IE6 and lower */ }

When there are two identical properties for a selctor, IE6 will apply the second property, even if the first property includes the !important directive. Other browsers will of course apply the !important declaration, enabling us to target IE6 with the subsequent rule.

Enable alpha-transparent PNG support

One of the most frustrating shortcomings of IE6 is its lack of 32-bit alpha-transparent PNG support. When displaying a 32-bit alpha-transparent PNG, IE6 replaces all transparency with an ugly grey background. Fortunately, this is a well-known and frequently addressed issue for which there are a wide variety of workarounds and solutions.

Apart from avoiding the use of alpha-transparent PNG images altogether, perhaps the simplest way to ensure visual compatibility with IE6 is to stick with fully transparent PNG images, which are fully supported and displayed properly in all browsers, including IE6.

A more practical approach is to apply alpha-transparency via 8-bit PNG format rather than the usual 32-bit format. To do so, use a program such as Adobe Fireworks (Photoshop does not work for this purpose), save your alpha-tranparent PNG image in 8-bit format, and then include in your design as usual. 8-bit PNGs may not look quite as good as 32-bit versions, but their alpha-transparency degrades gracefully to full index transparency in IE6. This method enables you to employ alpha-transparency in all modern browsers without getting the ugly grey background in IE6.

Of course, it is also possible to enable IE6-support for 32-bit alpha-transparency. There are many different scripts that enable such functionality, but all of them ultimately rely on a proprietary Microsoft AlphaImageLoader filter that may be included in your CSS file as follows:

* html .iepngfix { behavior: url(iepngfix.htc); }

To make this work, you need to upload these two files to the same directory as your CSS file. The first file is a blank gif image, and the second file is an HTC script that provides IE6 (and below) with the functionality required for 32-bit alpha-transparency. This is the most basic implementation of the AlphaImageLoader filter, but more advanced functionality is also possible using a wide variety of freely available scripts. Here are a few of my favorites:

Fix the broken box model

Early versions of Internet Explorer incorrectly interpreted the box model to include borders and padding in the calculation of the content width. For example, consider the following case:

div { border: 10px solid black; padding: 10px; height: 100px; width: 100px; }

In modern browsers, the height and width of this division are each calculated according to W3C specifications as 100px + 20px + 20px = 140px . In early versions of IE, however, the height and width are each calculated improperly as 100px . This discrepency is responsible for many design inconsistencies between standards-compliant browsers and older versions of Internet Explorer.

Fortunately, the broken box model was addressed in IE6, which is capable of rendering proper widths for web pages that include a complete <!DOCTYPE> . When a complete <!DOCTYPE> is present, IE6 switches to either “standards-compliant mode” or “almost-standards-compliant mode,” both of which cause IE6 to correctly interpret the box model. Conversely, when a complete <!DOCTYPE> is not included in a web page, IE6 reverts to “quirks mode” and interprets the box model incorrectly.

Thus, the box-model problem is easily fixed in IE6 by including a complete <!DOCTYPE> and designing in standards-compliant mode. If you need to work in quirks mode, the next easiest fix is to avoid applying padding or borders on elements for which you have specified a width. You can always apply padding and/or margins to the enclosed elements.

Even with these solutions, there may be situations where it is necessary to control the height and width of specific elements. In these cases, we may use the “Tan Hack” to get the job done:

#selector { border: 10px solid black; padding: 10px; height: 100px; width: 100px; } * html #selector { \height: 140px; /* targets IE5 and IE6 in quirks mode */ he\ight: 100px; /* targets IE6 in standards mode */ \width: 140px; /* targets IE5 and IE6 in quirks mode */ w\idth: 100px; /* targets IE6 in standards mode */ }

In the first set of rules, we apply our width and height as normal for all standard-compliant browsers. Then, in the second set of rules, we account for the broken box model in IE5 and IE6 quirks mode by adjusting the values for height and width to include the additonal padding and border widths. That’s quite a mouthful, so hopefully the code and comments will clarify the technique.

Fix min-width/max-width and min-height/max-height

Out of the box, IE6 fails to understand maximum and minimum height and width. This is incredibly sad for designers, as many layout scenarios require these properties to function properly. In modern, standards-compliant browsers, we can use the following CSS to acheive our goals:

div.max-height { max-height: 333px; } div.min-height { min-height: 333px; } div.max-width { max-width: 333px; } div.min-width { min-width: 333px; }

Of course, this is waaay tooo easy for Internet Explorer, which completely fails to understand these basic CSS properties. Fortunately, IE supports its own, proprietary expression attribute, which enables us to use JavaScript expressions to manipulate (X)HTML document properties such as max/min-width and max/min-height. For example, to specify a width property value via the expression attribute, we could use this:

div { width: expression(333 + "px"); }

..Which is equivalent to this:

div { width: 333px; }

There are two downsides to using IE’s expression attribute. First, as expressions are essentially JavaScript, they fail when JavaScript is disabled (or otherwise missing) in the user’s browser. Second, use of CSS expressions for min/max properties is very resource intensive and may negatively impact browser performance. Nonetheless, the setting of max/min-widths/heights remains an important tool in the web designer’s toolbox. With that in mind, here are some useful CSS expressions enabling complete min/max functionality in IE6.

max-width

/* max-width for IE6 */ * html div.max-width { width: expression(document.body.clientWidth > 776 ? "777px" : "auto"); } /* max-width for standards-compliant browsers */ div.max-width { max-width: 777px; }

min-width

/* min-width for IE6 */ * html div.min-width { width: expression(document.body.clientWidth < 334 ? "333px" : "auto"); } /* min-width for standards-compliant browsers */ div.min-width { min-width: 333px; }

max-height

/* max-height for IE6 */ * html div.max-height { height: expression(this.scrollHeight > 332 ? "333px" : "auto"); } /* max-height for standards-compliant browsers */ div.max-height { max-height: 333px; }

min-height

Fortunately, we can skip the crazy JavaScript/CSS expressions when applying minimum height in IE6. Thanks to Dustin Diaz, we can set min-height in IE6 with this morsel of valid CSS:

/* min-height for IE6 */ div.min-height { min-height: 500px; height: auto !important; height: 500px; }

Kill the double margin bug

Most web designers who have been designing sites for awhile are familair with IE6’s “doubled floated-margin bug.” This nasty bug rears its ugly head whenever you float an element (such as a <div> ) in one direction and then apply a margin in that same direction. For example, if we do this:

div { float: right; margin-right: 10px; }

..IE6 will (usually) double the size of the margin to 20px for no apparent reason whatsoever. Needless to say, this double-margin bug has wrecked many a fine web design, causing much pain and distress along the way.

Fortunately, this bug is easy to kill. Simply change the display type of the floated element from block to inline , like so:

div#selector { float: right; margin-right: 10px; } * html div#selector { display: inline; /* kill double-margin bug */ }

This solves the double-margin bug 99% of the time without issue. For those rare, unexplainable cases where this fix doesn’t work, you may need to workaround the issue by removing the margin and applying padding to either the parent element or to the floated element itself.

Clear your floats

Clearing floats is another common layout challenge, not only for IE6, but for many modern browsers. In a perfect world, an element that contains a floated element enlcoses that element entirely. In the imperfect world of web browsers, however, floats are frequently not entirely closed. When this happens, we say that the floated element has not been “cleared” by its parent element. Fortunately, there are several easy ways to clear your floats in IE6 and other browsers as well.

One of the oldest ways to clear your floats is to use the clearfix hack. This CSS technique works by generating content after the parent element using the CSS :after pseudo-class. The generated content then serves to clear the floated element. Here is a typical example:

.clearfix:after { content: " "; display: block; height: 0; clear: both; visibility: hidden; } .clearfix { display: inline-table; } /* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix { display: block; } /* End hide from IE-mac */

To use this method to clear your floats, place it into your CSS file and change all instances of .clearfix to the selector of the element that needs to clear its floated ancestors.

Another CSS method of clearing your floats is to simply float the container element. For example, if you float an image within a container <div> that fails to enclose it, simply apply the following CSS:

div { float: left; }

Then, if the containing element needs to behave as a regular block element, apply a width of 100% to force a line-break before the next element:

div { float: left; width: 100%; }

So far so good, but there is an even better method of clearing your floats. By simply applying an overflow value to the container <div> , it will automatically expand vertically and clear its floated children. Here is an example:

div.container { overflow: hidden; width: 100%; }

The width declaration is required for Internet Explorer and Opera, but it doesn’t need to be set at 100% ; rather, you may use any width and unit of measure that is needed. If you don’t want to specify a width , you may specify a height instead. For the overflow property, you may use any of the following three values:

auto – display scrollbars if content exceeds specified width

– display scrollbars if content exceeds specified width hidden – never display scrollbars even if content exceeds width

– never display scrollbars even if content exceeds width scroll – always display scrollbars, even if they’re not necessary

As well as this method works for clearing floated elements, there are cases where the overflow property can interfere with other aspects of the design. If this should occur, you may want to try limiting the scope of the overflow by using overflow-x:hidden; or overflow-y:hidden; . And remember, the width property may be replaced by height .

Fix other common IE6 problems

Wrapping things up, let’s run through a few other problems commonly experienced with IE6. These issues and their corresponding fixes are fairly straightforward, so I will spare you the lengthy diatribe and jump straight to the point. Keep in mind as you continue through this article that you should relocate and consolidate any IE6-specific hacks into an IE6-specific stylesheet, which should be included via conditional comments (see first section, above).

Fix relative positioning

Using position:relative in your designs is perhaps the easiest way to mess things up in IE6. Modern browsers display relatively positioned nested elements without issue, but IE6 frequently chokes up on even slightly complicated layouts. Fortunately, the solution is as easy as triggering hasLayout by adding zoom:1; to each relatively positioned element:

.selector { position: relative; } * html .selector { zoom: 1; }

Note that you should not apply zoom:1; to any inline elements. Doing so will cause IE6 to treat them as block elements. Keep this in mind for the following solutions as well.

Fix negative margins

Negative margins are useful in a variety of scenarios, and most browsers handle them with no problem whatsoever. Unfortunately, IE6 doesn’t like negative margins unless you apply relative positioning to the target element:

.selector { margin: -1.5em; } * html .selector { position: relative; zoom: 1; }

Note the addition of the zoom:1; declaration, which is required because of the relative positioning. Ain’t IE great?

Fix overflow problems

Using the overflow in IE6 will sometimes lead to unexpected, unexplainable display issues. Fortunately, we can resolve many overflow -related display problems by triggering hasLayout via — yep, you guessed it — zoom:1; . Here is an example:

.selector { overflow: hidden } * html .selector { zoom: 1; }

Another strange overflow -related issue is observed when font-style:italic; expands the width of its parent element. Thankfully, this nuance is easily resolved by applying the following CSS to the parent element:

* html .selector { overflow-x: hidden; }

Line up floated elements

When you float elements of a fixed width, they will align themselves horizontally to fit the width of the parent element. At least, that’s how it works in most browsers. In IE6, the floated items will not be displayed in a straight line, but rather will appear to stepdown in bizarre, staircase-like fashion. Fortunately, there are two ways to fix this issue. The first is to apply a line-height:0; declaration to the parent element:

.selector { float: left; width: 100px; clear: none; } * html .selector { line-height: 0; }

Alternately, you may prevent stepdown by applying a display:inline; declaration to the floated elements:

.selector { float: left; width: 100px; clear: none; } * html .selector { display: inline; }

Fix your list items

Lastly, if IE6 decides to add an extra set of list items ( <li> ) after your list ( <ul> ), adding an HTML comment has been known to magically resolve the issue. Here is what your source code will look like before and after applying the fix:

Before:

<ul> <li>Firefox</li> <li>Opera</li> <li>Safari</li> <li>Internet Explorer</li> </ul> <li>Internet Explorer</li> <li>Internet Explorer</li>

After:

<ul> <li>Firefox</li> <li>Opera</li> <li>Safari</li> <li>Internet Explorer</li> <-- IE6 fix --> </ul>

In Closing

With the CSS tricks described in this article, you are well-equipped to tame the IE6 beast and get it to behave when displaying your web pages. When it’s time to make your next design compatible with IE6, refer to this definitive guide for clear explanations and solutions for the most common IE6 issues. And of course, if you’ve got more tricks, ideas, comments, or questions, be sure to sound off in the comments section!

Related content