Solving Box Model Problems

By Dave Evans

Chances are you've arrived here either because you're having trouble with elements appearing different sizes in different browsers, or because you're reading ahead before you hit that problem! Either way, we're going to look at what causes the problem, and then see how easy it is to completely avoid it if you're in control of the code.

There are two ways that browsers calculate the box model:

The W3C way

The W3C Specifications state that:

The box width is given by the sum of the left and right margins, border, and padding, and the content width. The height is given by the sum of the top and bottom margins, border, and padding, and the content height.

So you add up the margins, padding, border and width to get the entire size of the object.

The Microsoft Way

Microsoft, as always, approaches things differently.

Microsoft prefers to subtract the padding and border from the width of the object, while margins (on divs at least) appear to be added.

So who does what?

Browser Mode Model
IE4, 5.0, 5.5 Standards Microsoft
  Quirks Microsoft
IE6 Standards W3C
  Quirks Microsoft
Firefox 0.8 > Standards W3C
  Quirks W3C
Opera 7.2 > Standards W3C
  Quirks Microsoft

In column 2, the mode is listed as either quirks or standards mode. Standards mode means the page has a valid doctype. Quirks mode means either an incomplete doctype or no doctype.

If you want to test your browser, or if your browser isn't in the list and you want it to be, you can test it using the following pages:

So to return to the results table, this means that if you just want to fix the problem for the latest browsers, you need only add a complete doctype. This will ensure your browsers interpret the dimensions consistently using the W3C model.

If you want to fix your site in Internet Explorer 4 and 5, you'll need to examine alternate ways of avoiding the problem. My personal favorite is explained below.

Extra elements

The box model problem only occurs when we have padding and borders, with a width. So, if we take two elements and nest them as shown below, we can assign the width to the outer one, and padding to the inner one.

<div id="width_div"><div id="padding_div">
Content
</div</div>

In this simple way almost all problems can be avoided.

Let's take another example: a vertical list of links, like a menu. Using CSS, we can define the width of the LI tag, and then define paddings and margins on the inner A tags in order to format the menu as we want it:

Click here for the box model menu example.

Don't forget to 'view the source' to see exactly how that menu is coded!

So why doesn't everybody use this simple method? The only issue with it is that it uses surplus HTML markup in order to correct the problem. If it was done purely using a CSS hack then it could be more easily removed in the future when all browsers standardize.

However, before we abandon this simple solution, don't forget that it will always work in all browsers, because it does nothing to mess about with who gets what dimensions. Complicated CSS hacks on the other hand may or may not work in the future, depending on those future browsers. So in my view, this method allows you to build a site and rest, content in the knowledge that it will always look good. Complicated hacks will require you to regularly check new browsers to make sure they are doing what you expect.

Let's take a look at these alternative solutions: these seek to supply only IE5 with a 'different' width, which will enable it to match the others.

The Tantek Hack

Here we use a voice family command, to take advantage of a CSS parsing bug in IE5 & 5.5. The wider width is read by all browsers. IE5.x trips on the voice-family command and stays with the first width. Other browsers then read the real width and adjust accordingly.

A further adjustment is then needed for older browsers like Opera 5 which have the same bug, but support selectors.

div.content {
   width:500px;
   voice-family: ""}"";
   voice-family:inherit;
   width:400px;
}
html>body .content {
   width:400px;
}

You can find the latest information on the author's site: TanTek.com

The Simplified Box Model Hack

This uses the escape parsing bug directly onto the CSS property:

div {
width: 400px;
}
div {
width: 500px;
width: 400px;
}

Opera 5 reads the first declaration and ignores the rest. IE5.x reads the first and second values, and applies the second. Everything recent reads all three and assigns the last width.

All the details

If you want a complete list of the CSS hacks, CSS Discuss is the definitive list.

Personally, I just use an extra tag. After all, one surplus div tag won't take up too much extra bandwidth...



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •