If you're not up to speed on your CSS, read about the CSS box model first and then come back here. As it explains, every non-inline element is considered by CSS as a box, which means you can set and customise the width and height of the content, the padding around the content, the border around the padding, and the margin around the border. This is quite good. Unfortunately, as is so often the case, Microsoft ruined it all by making the most widely-used browser (all IE versions prior to 6) fluff this up.

The Problem

The W3C decreed that the width and height assigned to a box should apply only to the content, with the overall width and height of the element being derived from the assigned values plus the padding, border and margin values. For example, look at this:

    div.block {width:100px; padding:10px; border:10px; margin:10px}

Now, <div class="block"> should have a width of 100px + the two sets of 10px for the padding, border and margins, thus giving us a total width of 160px. Where IE's box model falls down is in taking the width attribute and applying it to the whole box, putting the padding etc in the above example inside the 100px width. This isn't so good.

The Solution

The box model hack is a tricky thing - it must work on IE without confusing other browsers. The easiest way would be to remove the padding, border and margin settings from the box and nest it inside a second box which contains nothing but those settings. Unfortunately, this is an HTML-based solution which isn't so easy to clean up as a CSS-based solution (just in case the day arrives when browsers actually implement CSS properly). An ingenious CSS work-around was invented by a chap called Tantek Celik, which can be seen at http://www.tantek.com/CSS/Examples/boxmodelhack.html and which looks something like this:

    div.block {padding:10px; border:10px; margin:10px}  /* lose the width */

    div.block {width:160px;                             /* IE width */
               width:100px; }                           /* proper CSS width */

So how and why does it work? Well, IE has parsing problems. It can't cope with escaped characters, so it takes the value of voice-family (an arbitrary attribute, chosen for its relative obscurity) to be a backslash, which it thinks is a bit odd, but it doesn't complain. It then sees the close bracket and ends, ignoring all of the rest of the statement. Of course, other browsers see the two escaped quotes and take voice-family's value to be "}", thus ignoring the close bracket because it thinks it is quoted. It then resets voice-family to its previous value with voice-family:inherit and goes on to override the IE-specific width value with the correct one.

But! What about Opera? It supports the CSS box model properly but doesn't understand escaped quotes! Disaster! Unless, of course, you put this directly after the above hack:

    html>body .block {width:100px}

IE (prior to 6) hasn't got a clue what you're going on about, as it doesn't support CSS2 selectors. This makes sure that all CSS2-conforming browsers which don't like escapes can still get the correct width (just remember that it is important not to put spaces around the ">"). All is saved.

Now you know that the lack of ecaped character support is the backbone of the box model hack, you can probably write your own simplified versions of it. There are a few at http://css-discuss.incutio.com/?page=BoxModelHack although I haven't tested them all rigorously, so I don't know how well they work. Many people just settle for the tried-and-tested Tantek hack, which I think I shall do in my infinite laziness.