Wednesday, July 25, 2012

More IE6 info

This site has some great info on IE6 hacks, as well as links to yet more info!

[It would be a pity to find one day that the above link no longer works and all that info is gone.
I have thought about it and have decided to copy/paste the contents of that page below, in case that happens. has released this content under the following licence, which allows sharing.

<!--[if lt IE 7]>
    <style type="text/css">
IE, up to and including version 7, always use the nearest positioned ancestor to determine the stacking context for the element in question (what happen if a parent element has position:static explicitly?). IE7 treats the value 'auto' as 0 (zero) (a new stacking context is established?).

The 'select' element always appear above all other content by default, regardless of z-index. Their stack level can't be changed. Use iframe shim

Flash content will display above all other content by default, regardless of z-index. To work around this, explicitly set the flash window-mode to the default option of 'opaque', or use the iframe shim

The iframe shim works for the 'select' element, and most kind of embedded media content (flash)

IE (without a doctype), the declared height and width does include padding and border.

Avoid CSS expression if possible. CSS-expression is only available in IE 5 - 7. Microsoft removed it from some version of IE8. It can be used to emulate some CSS properties that IE does not support: position:fixed, max-width, max-height, min-width, and min-height. Here is the basic usage:
p {
    width:expression(some javascript code);

To use CSS-expression to emulate position:fixed in IE6:
#fixed {
  left: 10px;
  top: expression(body.scrollTop + 50 + 'px');

CSS expressions allow a web author to hook script expressions into the dynamic nature of HTML elements. The natural events of the page (onresize, onclick, onmouseover and so on) causing these expressions to be re-evaluated whenever content could possibly reflow. Once IE encounters the expression construct it binds the code directly to the object. If you use any fancy DOM work to disable either the entire stylesheet (stylesheet switching) or just to kill a single element, it won’t work as the expression is already bound to the actual elements.

If you try to apply the max-width to an element whose own width is dependent on the elements contained within. Reflowing content causes the onresize event to fire, which in turn may cause an infinite loop.

IE8 supports CSS expressions only if run in "compatibility" mode, but it does not support them in "standards" mode. If you do not need to maintain backwards compatibility with older versions of IE, you should convert any instances of expressions used in place of standard CSS properties to their CSS standard counterparts. For a complete list of CSS properties and IE versions that support them, see the MSDN CSS Attributes Index. If you do need to support older versions of IE in which the desired CSS properties are not available, use JavaScript to achieve the equivalent functionality.

If you are using CSS expressions for dynamic styling, it makes sense to rewrite them as pure JavaScript to both improve performance in IE and get the benefit of supporting the same functionality in other browsers at the same time.

IE support something called CSS expression. A lot of time, people use it to address CSS incompatibilities across browsers. An expression is just a javascript expression that IE will execute and the result is set as the CSS style. In this case, here is a way to get around the lack of support for CSS min-width in IE. You can say that when this expression is evaluated, look at the body width, if it is less than 600 pixels, set it to 600 pixel, otherwise set it to "auto". They problem is that CSS expressions are executed many more time than you expects. They are execute everytime you move the mouse around the page. If you have this expression, during the typical user interaction with the page, the expression is executed between 10 to 50 thousand times, so if you aren't aware of that and you've done a little heavy in your javascript, it can really impact the load time of the page. There are way to get around it. If we have a one time expression, it only has to be evaluated once during the lifetime of the page, we can do a one time expression where the evaluation of the expression overwrite itself. Or we can write an event handler. As in the case of min-width, rather than using an expression, add an event handler to the resize event. That what make CSS expression easy. They are tie to events automatically so that you don't have to worry about that. But that is what is bad about them. They are tied to all the events, so they are executed all the time. So do the heavy lifting yourself, figure out which event you need those expression to be evaluated against, and tie it to those events.

A div with position:absolute acquires display:inline. To get around this issue, always explicitly set the position of the div using either (top, left), or (bottom, right), or try adding zoom:1

Use conditional comment to fix these IE-specific issues. Use conditional comment so that your CSS can be validated. Also readTarget every version of IE from a single stylesheet (before using this technique, we need to see what Google Page Speed says about descendent selectors)

The box model bug: Explorer 5 for Windows does not support the W3C box model. Explorer 6 does,
but only in Strict mode. In W3C box model, when we declare the width of an element, we are declaring the width for its content area. This does not include border, and padding.** In IE box model, when we declare the width of an element, we are declaring the width of the entire element. This include the width of the content area, border and padding. The fix (most of the time) is to include proper DOCTYPE. If that does not work (for example, you have to support IE 5.5), then use the simplified box model hack (the Tan hack, named after Edwardson Tan):
* html div {  /* This is the Tan hack */
  width: 130px;
  w\idth: 100px;

The star at the beginning of the selector is the universal selector, which applies to all elements. "html" is supposed to be the root element. All versions of Internet Explorer seem to believe that there is a mysterious "wrapper" element surrounding "html". The selector in question (* html div { }) picks out any div that is enclosed (however deeply) inside "html", if "html" is enclosed in any element whatsoever. IE thinks that the star refers to this "wrapper", and then sees that yes indeed, "html" is enclosed inside it. Only IE believes this condition exists.

However, all other browsers see "html" as the true "root" element, and so the star can't refer to any real element. This causes all non-IE browsers to ignore all rules following that selector. Thus, the entire Tan hack is totally invisible to all browsers except Internet Explorer.

In the hack selector, the star and "html" parts are required, but the div I gave as an example would, in practice, be replaced by the element to be targeted. Instead of "div", it could be "p", "ul", ".myclass", or whatever you need. It is best to be as specific as possible in order to target only those elements that require different values.

The w\idth: 100px; is for IE6 and IE5.5 on mac. It turns out that IE5.x/win cannot handle any property name having such an escape within it, but IE6 and IE5/mac correctly ignore the escape.

The escape character must be inside the property name (whatever that may be), and it must not come just before any of the first six alphabetical characters, meaning: a, b, c, d, e, or f. If this is done it will be interpreted as a "hex" character, messing up the hack. Luckily, all property names have at least one suitably "escapable" character.

The Tan hack does its job well and won't cause trouble for with version 5 and above browsers, but IE4.5/mac may have trouble with it. You will need to test to be sure.

If IE6 is in quirks mode it will be using the old box model, and will need the same "width" value that IE5.x/win does. However, IE6 will still not be fooled by the escape, and will read the escaped value, thus defeating the hack, and rendering a smaller than desired box. Make sure the doctype you use puts IE6 in "standards" mode.

Using an <?xml…?> declaration at the top of the document, while recommended for some doctypes, will wrongly throw IE6 into "quirks" mode. It is not required, so be careful if you use the declaration, and test thoroughly! (See the Rendering Mode and Doctype Switching article at CMX for more on this topic.)

If your page must be in "quirks" mode for some reason, doing something different with the Tan hack may be necessary. First, the Tan hack is modified by removing the second value (the one with the escape in it). That way IE6 gets the same value as IE5.x/win. But now IE5/mac (which does not go into "quirks" mode) will also use that value, and get it wrong. So, to hide the Tan hack from IE5/mac, do the following:
div {
    width: 100px;
    padding: 10px;
    border: 5px solid black;
    margin: 10px;

/* A CSS comment before the hack \*/
* html div {
    width: 130px; 
/* Another CSS comment after the hack */

Look at the top comment. See that escape just before the closing tag? Because of that escape, IE5/mac fails to recognize the closing tag, and so fails to read the entire Tan hack. The second comment below the hack provides a closing tag for IE5/mac's benefit. In this way, IE5/mac reads only the value in the normal code block before the hack. This Mac hack, called the Commented Backslash hack, was discovered by Sam Foster. Version 2, the one we're using here, was suggested by James Craig.

For detail explanation of the Tan hack, refer to The Box Model Problem

The double margin bug. Let’s say we need that floated to the right, IE 6 will double its margin. The commonly thrown-around “fix” for this is to add “display: inline;” to the div. Side-step this bug whenever possible. If you really need to push that box away from the right side of it’s parent element, you can likely do so by adding padding to the parent element. This bug does not affect padding, so you can offen get away with adding padding to the side you need an achieve the same result. "display:inline" only causes IE6 to not double the margins, the elements are still rendered as blocks – it’s a bug to fix a bug. "display: inline-block" also works. It basically combines both inline and block displays, meaning the element is still inline, while allowing the block level style of padding, fixed width, and such. “display: inline;” works to eliminate the double-margin bug because floated elements, by their nature, are block-level elements. doesn’t matter if “display: inline” is applied to that element. modern browsers simply ignore such non-sense, but ie 6 understands it. Also, all floated elements should have a declared width.

Some elements disappears when you interact with something on the page (we cannot position something over certain elements). I was using the coolframe menu system. When I mouseover a menu, my select elements disappear. The coolframe menu hide the select elements because the select element is special. Later version of the coolframe menu use the iframe hack(put an iframe on top of the select element), but it still appears as though the select element somehow disappeared. Better solution may be:
  • make sure that the select elements are not in the way of the menu
  • do not use the normal select element (use a jQuery plugin or another javascript library / plugins that simulate the select element)
  • only use the iframe shim if we need to hide the select element (we need to determine which select elements need to be hidden based on their position)
Explorer for Windows does not support the child selector (>), the adjacent sibling selector (+) and the attribute selector (p[class]).

Explorer for Windows does not support the :focus and :first-child pseudo-classes.

Explorer for Windows does not support the W3C definition of background-attachment: fixed on elements other than the <body>.

IE does not support min-height and min-width. IE6 does support min-height declaration on <td>s in tables with table-layout: fixed (which, in turn, is not supported by any other browser).

IE 6 does not support min-height and min-width. Fortunately, IE 6 treats the regular height property like modern browsers treat min-height.

Min-height is incredibly useful for something like a footer. Say your footer needs to be at least 100px tall because you are using a background image down there, but you don’t want to set a static height because you want it to grow nicely if, say, the text size is bumped up significantly. Min-height is perfect for this, but using it alone will get you no height whatsoever from IE 6. In a bizarre twist of luck, IE 6 treats the regular height property like modern browsers treat min-height. See also Maximum and Minimum Width Solution for All Browsers

IE 6 does not support max-height and max-width. See max-width in Internet Explorer and Maximum and Minimum Width Solution for All Browsers

IE 6 involuntarily cause "stepdown" on floated block element. Normally when floating objects you can count on them lining up vertically until they run out of horizontal space, at which point, the floated elements will wrap / stepdown. IE 6, however, appends a line break effect after each floated block element which will cause involuntarily “stepdown”. The fix is to make sure the line-height in the parent element is set to zero (0), or that the elements being floated are inline elements. See preventing stepdown. If this does not work, try setting zoom:1 on the parent element

No hover state. IE 6 only support the hover pseudo-class on anchor (<a>) elements, and even then you don’t get them if your anchor doesn’t have a href attribute. The solution here is to wrap the element in an anchor (<a>) tag, use a proprietary fix, or just deal with not having hover states on everything you want.

No alpha-transparent PNG support. Regular non-alpha transparent PNG files work fine without any fix in IE 6, and are often better than their GIF sisters. See different t echniques for applying the PNG hack. Consider using PNG8. IE6 can't deal with alpha transparency in PNG 24

No support for position:fixed. IE6 does not have support for position:fixed.

Simulate position:fixed using javascript. Instead of using CSS expression, use some sort of onscroll
handler. Instead of using position:fixed, change it to position:absolute. Register these elements in an array, and then the onscroll handler move these elements as the page is scrolled. We may need to remember the position of each elements, or the previous scroll position. The onscroll handler remembers the previous scroll position, compute the delta, and apply the delta to these elements.

Eric Bednarz has found a pure CSS solution to this problem, but technically it can be tricky. For instance, when you use his fix you cannot use position: absolute normally. Read his page well if you want to implement his solution.

IE6 incorrectly trigger the onresize event handler. See

IE6 has an issue with Flash and HTTPS (no-cache headers are used):

IE6 cannot deal with compress content
DOCTYPE does not work with document.body.clientHeight. See Get viewport size (width and height) with javascript, and Why DOCTYPE affects document.body.clientHeight

DOCTYPE does not work with document.body.scrollTop or element.scrollTop. This is the same issue with document.body.clientHeight. Use document.documentElement.scrollTop instead. Also, scrollTop only seem to work on elements for which overflow is declared.

Problem with floated inline element. Floated elements, by their nature, are block-level elements. Therefore, this is not a problem with IE. This is a problem with your code. Either change the element to block-level elements, or consider using absolute positioning.

Problem with in-ability to have very small height. (I ran into this problem when I was trying to create a line going across the page using a DIV. This did not work for IE6, and so I had to use the <hr> element which looks thicker than I wanted.) IE simply refuses to size an element smaller than the set font size. Simply setting the font size to 0 lets you have an element as small and short as you like:
     border: solid 1px #36F;  
     height: 1px;  
     font-size: 0;  

Another way to deal with this problem is to set overflow:hidden so it collapses to the intended height.

Problem with checkboxes displayed out-of-place when they are inside a ul element. This is specific to IE-7. To work around this issue, assign position:relative on the ul element.

Problem with text-indent. Do not use text-ident. Use margin, padding, or border to achieve the same effect.

Problem with xml prolog: Avoid the unnecessary ?xml prolog. 20020404 Prerit Bhakta noted that if you include the ?xml prolog:
<?xml version="1.0"?>

then IE6/Windows uses the quirky box model. Since the ?xml prolog is unnecessary, omit it.

Problem with position:relative elements overflowing its container. This bug rears its ugly head when in a layout you set the parent container’s overflow property to auto and place a relatively positioned item inside it. The relatively positioned item violates its parent element’s boundaries and overflows outside. The easiest way to fix this annoying bug is to just position the parent element relatively too.

Problem with space between list items. IE 6 adds vertical spacing even none is specified. See the last bug on 9 Most Common IE Bugs and How to Fix Them for detail. An easy solution is to float the list items left, and clear left:

Problem with floated elements and overflowed content. If you've got two floated elements and the content from the left container overflows then, in IE, the container grows and inevitably pushes the right container below it. This is usually a sign that you've messed up your margins, widths, or padding on one of these containers but Firefox (et al) won't reveal this. Using something like overflow:hidden or overflow:scroll on a container can help prevent IE from allowing the content to push the width of the container but you're better off trying to fix the issue in the design.

Problem with IE6 displaying blank page if the page specify a character set UTF8:

If a page specify a character set UTF8 via a meta tag (the page has a valid DOCTYPE), IE6 will display a blank page. This problem may also be caused by the no-cache meta tag.

IE6 collapse block level element if we do not define height, but we define overflow (either auto or hidden or whatever). Use "zoom: 1" in your ie6.css

IE triggers HTTPS warning if we have an iframe or an img tag that we forget to specify the src attribute.

IE triggers HTTPS warning if we have CSS background null

IE6 does not understand attribute selector. And if we combine selectors, the attribute selector break other selectors as well.

**IE6 and 7 only support inline-block for elements that are natively inline. Luckily, in IE, elements that have layout and are inline behave as inline-block elements. The initial value for vertical-align is baseline. If you want your blocks to be vertically aligned on their center, use vertical-align:middle.

Missing borders. Sometimes, the solution will consist of adding a margin, just for IE, around the box that has the border, or around the parent element, or making the element behave like an inline-block:
*display: inline;
*zoom: 1;

Invalid argument. Here are the known cause of this frustrating error:
  1. If a DOM attribute is of type number, say colspan, then setting colspan="something" (or more exactly myTd.colSpan = "something") cause this error.

Problem with JSON: Given a JSON object:
    name1: value1,
    name2: value2,
    name3: value3,

IE will results in a javascript error. This JSON object works fine Firefox. If you use SpiderMonkey to check the syntax, SpiderMonkey does not detect this as error.

The best way to deal with these incompatibilities is to make sure that the correct layout of your page doesn't depend on them. If you use these problematical selectors and declarations not for fundamental CSS declarations but only for nice extras, you can ignore Explorer for Windows' incompatibilities. For instance, the :focus pseudo-class allows you to define a style for a focused form field. Although this extra style is nice to have, your page can do without it. Therefore you can safely use :focus and ignore Explorer Windows' lack of support.

You could use the famous Box Model Hack, or you could decide the minor differences aren't worth the trouble. Fluid thinking can solve many problems, not by hacking your way through browser incompatibilities, but by embracing a different, more web-like way of thinking.

Sites that document IE-specific bugs:
JavaScript in Internet Explorer 8
Simulating fixed positioning in IE6
Defining Document Compatibility
PIE makes Internet Explorer 6-8 capable of rendering several of the most useful CSS3 decoration features
Internet Explorer In A Web Designer’s Life – Problems And Solutions
HTML5 elements in Internet Explorer without Javascript.
Cross-Browser Compatibility with CSS3
CSS3 selectors for IE
HTML5 Cross browser Polyfills
CSS3 Compatabilty Tools, Resources and References for Internet Explorer
CSS Enhancements in Internet Explorer 6
How Internet Explorer 8 document mode affects JavaScript
How To Attack An Internet Explorer (Win) Display Bug
CSS Enhancements in Internet Explorer 6
About Conditional Comments
Recap of Compatibility View
The IE/Win Disappearing List-Background Bug
Explorer 6 Duplicate Characters Bug
Browser-compatibility Issues
Min-Height Fast Hack
Space between list items in IE
Cross-Browser Transparency via CSS
Cross-Browser Variable Opacity with PNG: A Real Solution
Clearing floated images in body text
Ultimate IE6 Cheatsheet: How To Fix 25+ Internet Explorer 6 Bugs
How to resolve browser compatibility issues while working with JavaScript, AJAX and XML
IE6 Peekaboo Bug
Internet Explorer vs. the Standards
Explorer Exposed!
Ultimate IE6 Cheatsheet: How To Fix 25+ Internet Explorer 6 Bugs
Flash of Unstyled Content (FOUC)
The simplified box model hack (IE5)
Overflow problems in Internet Explorer
Internet Explorer 6 and the Expanding Box Problem
Fix IE7 scrolling background problem in textarea form fields
10 ways to make Internet Explorer act like a modern browser
Fix IE7 scrolling background problem in textarea form fields
Definitive Guide to Taming the IE6 Beast
CSS opacity filter syntax for IE8
IE and DOMReady bug
Kick-ass CSS3 Support in IE6, 7, and 8
HTML5 Way Around For IE
How to use RGBA() in IE
Got IE6?
Did Internet Explorer get the Box Model Right?
Internet Explorer Select Width Bug Workaround
Coding for IE6 = Progressive Enhancement
Enhanced Scripting in IE9: ECMAScript 5 Support and More
IE’s big leap forward; CSS3 selectors fully supported
Fixing HTML5 Loaded Via Ajax in IE
More IE9 goodness and elementFromPoint()
IE-only Styles: Where Should They Be Placed?
How To Attack An Internet Explorer (Win) Display Bug
Absolutely Buggy II
Box Model Hack
Fluid thinking
Browser Compatibility Development Guide
Commented Backslash MacIE5 CSS Hack - v2

ps: Comments and/or links to this article are most welcome!