The Good, The Bad, and the Ugly

If you are trying to do pixel-perfect cross-browser CSS layout, you will often run into problems with IE5x PC because it radically mis-implements the box model as prescribed by the W3C. There are several workarounds for this problem, not the least of which is to simply not design with pixel precision in mind. But assuming you just have to get it pixel-perfect, no way around it, well here are a couple of workarounds that can help you (#3 and #4 are the recommended methods):

  1. Nest Your Boxes
    The problem with IE5x PC's box implementation is that it incorrectly puts the padding and border of a box WITHIN its stated width. The W3C states that padding and border are to be added to the width, and Opera, IE5 Mac, and Gecko (NS6, Mozilla, Galeon) correctly implement the box model. So a DIV with a stated width and also some padding and a border will have very different screen display in these two sets of browsers. One solution to this problem is to not assign padding or border to a DIV to which you have assigned a width. If you don't need a border effect, you can get your padding by simply setting margin or padding on all the box elements (DIVs, Ps, BLOCKQUOTEs, etc) contained with the DIV. If you need a border, simply nest a DIV within that DIV, do not assign it a width (it will fill up its parent DIV), and assign a border to the nested DIV. The problem with this technique is that you dirty up your markup with extraneous DIVs. Wouldn't it be better to move our workaround up into the CSS so that our nice structural mark-up remains pristine?
  2. Use CSS2 selectors
    IE5x PC does not support the CSS2 child selector while IE5 Mac, Gecko and Opera do. IE5x PC will simply ignore all rules assigned using this selector, so if we initially set width, padding, and border values that work with IE5x PC's broken box model in rule using a CSS1 selector, then override those incorrect values with proper values in a rule using a CSS2 selector, everybody will be happy. Well not really, but before I explain the problem with this let me show you how it looks. This DIV will be 200 pixels wide on the screen in IE5 Mac and PC, Opera, and Gecko:
    
    #myDIV
       	border:10px solid black;
    	width:200px;
    	}
    html>body #myDIV {
    	width:180px;
    	}
    
    Ok, now here's the problem: what if a browser comes on the market that does not support CSS2 selectors, but gets the box model correct? You guessed it. That browser not see the width value intended for correct box-model implementations, because this hack depends on the existence of CSS2 selectors to correct bad values set for IE5x PC. Now, what if this new browser is positioned to take over IE5x PC's position as the predominant browser on the web? Well, that worst-case scenario seems to be happening. We've all been using this hack with the blind assumption that IE6 will fix both its box-model implementation and add support for CSS2 selectors. However, the IE6 public Beta that came out last week does not have support for CSS2 selectors, but yes, you guessed it, they fixed the box model. Even if they add CSS2 selector support in the release version, this whole situation so clearly highlights the deficiency of this workaround, and imposes such restrictions any other future browsers that may not wish to support CSS2, that we have to come up with a better system.
  3. DON'T DESIGN WITH PIXEL PRECISION IN MIND
    If you can avoid it, you are better off keeping your markup and your style sheets clean of hacks and workaraounds. I want to make that clear here, because the workaround that follows, while being on one hand beautiful and inspired, is also ugly and in many ways antithetical to the spirit of the W3C's recommendations.
  4. Exploit an IE5x PC CSS parsing bug -- RECOMMENDED
    This hack allows us to prematurely close a style rule in IE5x PC because of a bug in its CSS parsing code. Here, let me just show you:
    
    #myDIV
       	border:10px solid black;
    	width:200px;
    	voice-family: "\"}\"";
    	voice-family: inherit;
    	width:180px;
    	}
    html>body #myDIV {
    	width:180px;
    	}
    
    I weary of writing all this, and I have work to do (poor me) so I am going to point you to Tantek Celik's explanation of how this works. Tantek Celik is the mind behind much of IE5 Mac, a contributor to both CCS2 and CSS3, and also the architect of this workaround, so let's let him explain.

    This workaround is now my recommended method for dealing with IE5x PC's broken box model. You will find it in use here on this site in place of the CSS2 selector hack that I was using before the release of the IE6 beta. Thank you and good night.