The techniques presented here are alternatives to the Tantek �elik Hack, Simplified Box Model Hack, and modified SBMH. As with these three the following alternates are meant to provide IE5.x/Win a width (and/or height) value of its own to compensate for its erroneous implementation of the CSS Box Model.

The workarounds exploit the various forms of comment bugs found in IE (both for Windows and the Mac) to hide declarations from one or another version of IE. Techniques 2 and 3 in addition employ the !important declaration.

In the syntax sections below the term "whitespace" is mentioned a number of times. Whitespace is used here in the same sense as in the CSS Specifications. A whitespace may be a blank space, a tab, or a carriage return.

All techniques presented here are valid CSS.

You may wish to test your browser's response to the hacks. You may also want to see a comparison of how all box model hacks fare in your browser.

Technique 1

Syntax

<selector>           
{
  /* specify borders and paddings if any */
	
  width: <content width + paddings + borders>;
  width/* */:/**/<content width>;
  width: /**/<content width>;
	
  /* other declarations may appear anywhere in this rule */
}

The three width declarations above must be specified in the order shown or some browsers will not receive the proper value.

Syntax Details for Technique 1
Declaration Critical Non Significant
width/* */:/**/<value>;
  • There must be no whitespace between width and comment
  • There must be at least one whitespace inside the comment adjacent to width
  • There must be no whitepace between comment and value
  • There may or may not be whitespace before and after the colon
  • There may or may not be whitespace inside the comment adjacent to value
width: /**/<value>;
  • There must be no whitepace between comment and value
  • There may or may not be whitespace before and after the colon
  • There may or may not be whitespace inside the comment adjacent to value

How It Works

The first width declaration is for IE5.x/Win. This is the only declaration among the three that it will recognize. The value specified herein must be the sum of left and right paddings, left and right borders, and content width.

The second width declaration is hidden from IE5.x/Mac and IE5.x/Win. It is recognized by browsers (including IE6) which do not have these particular comment bugs. The value specified herein should be the content width of the block.

It is important to understand that IE5.0/Win ignores a declaration such as width/* */: <value>, as well as the declaration immediately following it. IE5.x/Mac on the other hand ignores only the declaration where the comment is found. Because of this peculiar behavior both the second and third width declarations above are hidden from IE5.0/Win. This behavior is imperative since the hack hinges on it.

The third width declaration is hidden from IE5.5/Win but because of the comment hack in the second declaration it is also hidden from IE5.0/Win. It is, however, recognized by IE5.x/Mac and other browsers that do not have this particular form of comment bug. The value specified herein should be the content width of the block.

Example

The two blocks below should both be 500px wide. IE5.x/Win, however, will display the first one with a total width of only 400px. The second block contains the hack which should supply IE5.x/Win its own width value while supplying other browsers another value.

Without the hack:

padding: 0 50px; text-align: justify; width: 400px; background: #ec0;

With the hack:

padding: 0 50px; text-align: justify; width: 500px; width/* */:/**/400px; width:/**/400px; background: #ec0;

Test your browser's reactions to the hack.

Technique 2

Syntax

<selector>           
{
  /* specify borders and paddings if any */
	
  width: <content width> !important;
  width: <content width + paddings + borders>;
  width/**/:/**/<content width>;
	
  /* other declarations may appear anywhere in this rule */
}

The three width declarations above must be specified in the order shown or some browsers will not receive the proper value.

Syntax Details for Technique 2
Declaration Critical Non Significant
width/**/:/**/<value>;
  • There must be no whitespace between width and the adjacent comment
  • There must be no whitespace inside the comment adjacent to width
  • There must be no whitepace between the comment adjacent to value
  • There may or may not be whitespace before and after the colon
  • There may or may not be whitespace inside the comment adjacent to value

How It Works

The first width declaration is for browsers that understand the !important rule and get the CSS box model correctly. This declaration is necessary because the third width declaration is hidden from IE5.x/Mac.

Declarations with !important are recognized but not given any importance by all IE/Win so when the property is redeclared (in the same rule) IE/win will apply that value instead (which is not the case with browsers that properly implement !important).

The second width declaration is understood by all browsers but is intended for IE5.x/win only because in other browsers the other width declarations should override this value.

IE5.0/win and IE5.x/mac ignore a declaration when a comment comes right after the property. IE5.5/win meanwhile ignores a declaration when a comment comes right before or right after the value. The third width declaration will, therefore, be ignored by IE5.x/Win and IE5.x/Mac. IE6/Win has no problem recognizing it and since it does not implement !important it will pick up this width value. See the discussion on comment bugs for further details.

How Browsers Will React to the Hack

Example

The two blocks below should both be 500px wide. IE5.x/Win, however, will display the first one with a total width of only 400px. The second block contains the hack which should supply IE5.x/Win its own width value while supplying other browsers another value.

Without the hack:

padding: 0 50px; text-align: justify; width: 400px; background: #ce0;

With the hack:

padding: 0 50px; text-align: justify; width: 400px !important; width: 500px; width/**/:/**/400px; background: #ce0;

Test your browser's reactions to the hack.

Technique 3

Syntax

<selector>           
{
  /* specify borders and paddings if any */
	
  width: <content width> !important; 
  width /**/:<content width + paddings + borders>;
	
  /* other declarations may appear anywhere in this rule */
}

The two width declarations above must be specified in the order shown or some browsers will not receive the proper value.

Syntax Details for Technique 3
Declaration Critical Non Significant
width /**/: <value>;
  • There must be at least one whitespace between width and the comment
  • There may or may not be whitespace before and after the colon
  • There may or may not be whitespace inside the comment

How It Works

The first width declaration is for browsers that understand the !important and get the CSS box model correctly.

Declarations with !important are recognized but not given any importance by all IE/Win so when the property is redeclared (in the same rule) IE/win will apply that value instead. Because of this IE5.x/Win will apply the value in the second width declaration.

The last width declaration has a property followed by whitespace followed by a comment. This effectively hides the declaration from IE6 but not from other IE versions (both Windows and for the Mac). It is necessary to hide this width value from IE6 because it does not implement !important but gets the CSS box model correctly. See the discussion on comment bugs for further details.

How Browsers Will React to the Hack

Example

The two blocks below should both be 500px wide. IE5.x/Win, however, will display the first one with a total width of only 400px. The second block contains the hack which should supply IE5.x/Win its own width value while supplying other browsers another value.

Without the hack:

padding: 0 50px; text-align: justify; width: 400px; background: #0ce;

With the hack:

padding: 0 50px; text-align: justify; width: 400px !important; width /**/: 500px; background: #0ce;

Test your browser's reactions to the hack.

Comparison of the Various Box Model Hacks

All box model hacks have their drawbacks.

The Tantek Hack is, to understate it, homely and is not easily comprehensible. A more important point, however, is that it requires a "be nice to Opera 5" child selector rule to serve that browser the correct width value because just like IE5.x/Win it is fooled by character escapes. In addition, character escapes will cause NS4.x to ignore the entire style sheet (yes, NS4.x will disregard all the CSS rules).

As with the Tantek Hack the character escape technique of the SBMH does not sit well with Opera 5 and NS4.x. Opera 5 dumps the entire rule where the escape is found, while NS4.x ignores the entire stylesheet. This means that at least two (maybe even three), nearly identical, rules with the same selector must be specified: one with an unescaped width and another with a character escaped width. Although using escapes is a simple and elegant solution, the necessity of specifying several rules defeats its initial simplicity.

The alternate box model hacks obviate the need for "be nice to Opera 5" rules since there are no character escapes to worry about. Hence, only one rule set is necessary. However, these alternates too have liabilities. The reliance of techniques 2 and 3 on !important puts an additional burden on the web author. One characteristic of !important is that when a simple type selector (specificity = 1) has an !important declaration in one of its properties all elements matched by that selector will take on that value, regardless of the specificity of the succeeding selectors. For example, given:

div {width: 400px !important;}

div#someblock {width 600px;}

div#someblock which has a specificity of 101 will have a width of 400px and not 600px. In fact all div's will have a width of 400px. The only way for div#someblock to receive the value of 600px value is to declare it as !important in order to override its default width of 400px.

Therefore, techniques 2 and 3 are best employed when the selector has a moderate to high specificity. This will avoid any possible clashes between various block elements, and also help preclude the use of !important to override previously set widths that have been declared as !important.

All 3 alternates, moreover, are very meticulous about where whitespace should and should not be found. As evidenced by the tables of syntax details, it is critical to have and not have whitespace in the correct places. Failure to implement the exact syntax will lead to not so pretty results on screen.

Finally, in fairness to the Tantek Hack, those comment riddled declarations are creatures only their mother (or should I say father) could love and understand.