By: John Gallant , Holly Bergevin ,
Page 1 of 2
When breaking out of using tables and moving toward using Cascading Style Sheets (CSS) positioning for laying out elements on a page, it is important to become familiar with the W3C Box Model. At first, the box model may be confusing, but it is a necessary concept to grasp. Unfortunately, simply understanding the W3C box model is not the only thing you need to make your web pages look similar in different browsers. Come along as we explore the Box Model, the browsers that get it wrong, and what to do about them.
Note: While layout editors are very good at tabled layouts, and applying CSS to those layouts, the current state of browser development leaves much to be desired when attempting CSS positioning. Because of this, CSS "hacks" are sometimes required to persuade certain browsers to play nice with such positioning. At the present time no layout editor can fully deal with these positioning bugs, and manual text editing is necessary to work around the problems.
This article is intended for people familiar with with CSS syntax and usage. If you are new to CSS, see Adrian Senior's excellent article, CSS: An Introduction, here at CMX.
The box model
A table structure consists of rectangular cells within a rectangle. A CSS "box" can be thought of as a table with only one cell. Such a box can be given borders, transparent margins outside the borders (keeps other boxes away), and transparent padding inside the borders (keeps the content away from the edges of the box). These can be applied to each side of the box separately. Inside the padding is the "content area", which, you guessed it, holds the content of the box.
If the box has no given dimensions, it is called "fluid" or "liquid." This means that it horizontally fills the container box surrounding it, and expands vertically to enclose whatever content is within it. For the most part, such fluid boxes are quite reliable.
But let's say you want to give horizontal and vertical dimensions to the box. Naturally these properties are called "width" and "height." But what exactly is "width?" After all, there's the content area, then the padding, the border, and finally the margin on the outside. As it happens, the W3C decided that the width dimension goes from the inside edge of the left padding to the inner edge of the right padding. If there is no padding, the width is measured from the inside edge of the left border to the inner edge of the right border.
A closer look
Let's make a simple box and see how it works. Boxes are created by "block level" elements like <table>, <p>, <blockquote>, <ul>, <li>, and the generic <div>, among others. Some layout editors, such as Dreamweaver, use <div>s to create absolutely positioned "layers." However, <div>s are actually simple generic container boxes without default properties of any kind. If they are not positioned they are "static", meaning they are placed within the normal flow of the document as it is laid out, just as <p>s and other block level elements are.
Each "block level" element is displayed on a line by itself, so to speak, and will force any element coming after it to begin on a new line. By default, a box is as wide as it can be without spilling out of its containing element, in this case the <body> element. So, to keep the box from being full width we write:
<div>content goes in here</div>
...and we give it this CSS:
border: 5px solid black;
margin: 10px; }
Here is the result of the above code. The "width" of the box is defined as 100px, while the "height" is left undefined, so the height is controlled by the amount of content present. The more content, the taller the box.
Note: The margins and padding are normally transparent, but are shown colored in this example graphic.
According to the W3C specs, the width of the white content area between the grey padding zones is 100px. The padding, borders and margins are added on to the outside of the "width", to arrive at a total of 130px for the visible bordered box dimension, or 150px from outer (purple) margin edge to outer margin edge. That's what you see in the upper box.
The interesting part
As it happens, when Microsoft first implemented the box model for Internet Explorer 5/win, it was apparently decided that the standard box model was sub-standard. So, they arranged for the box "width" declaration to refer instead to the outer dimension of the visible bordered box. In other words, in IE, "width" referred to the area within the outer edges of the black borders, but not including the margins (see the above example). The same decision was made for "height," too.
This meant that if the box was given borders and/or padding, the content area (and the whole box) would be smaller when viewed in IE. A major hassle for sure! It affected most every box that was assigned "width" or "height". Even though no height is assigned to our example div, the problem can also affect that dimension.
Fortunately, Microsoft saw the error of its ways and corrected IE's box model in IE6, but only if it is in "standards mode". If it is left in "quirks mode" it still emulates the old IE5.x/win box model. By the way, IE5/mac always obeyed the standard box model. Go figure. (See the Rendering Mode and Doctype Switching article at CMX for more on "modes.")
All fine and dandy, but what about IE5.x/win? Several zillion people still use that browser! Well buckle your seatbelts, kiddies, it's time to shift out of neutral.
The infamous "Box Model Hack"
There are several different versions of the Box Model hack, but all seek to feed IE5.x/win (and only that browser) a width or height value such that it will render the box to the same dimensions as a browser using the standard box model. For the above example box, that would mean adding the widths of the left and right borders (5px each) and padding (10px each) to the desired content area width, thus:
5px + 5px + 10px + 10px + 100px = width: 130px
Being the complex beasts they are, browsers can sometimes be shown CSS code and will (for one reason or another) totally ignore it. The first box model hack was the good old Tantek hack, which takes advantage of an IE5.x/win parsing bug involving the escape character: "\". This does the job, but it has some problems. It is difficult to understand and remember, it affects Opera adversely (requiring another hack), and it causes Nav 4 to ignore ALL CSS styles! Not good.
Then came the simplified box model hack which improves things, but still breaks Nav 4. Finally came the Tan hack (named for Edwardson Tan), which affects only IE browsers and no others. It is simple and easy to remember, and can't harm any future browsers. A miracle hack!