Toward a more standards compliant Internet Explorer
Published on February 6, 2003
Microsoft has corrected Internet Explorer’s nonstandard CSS box model by using a doctype “switch” at the top of an HTML document. Any one of several different doctypes can be placed at the start of the page file, telling modern browsers how to handle the code. For instance, if I use the “strict” doctype (I like the sound of that), Internet Explorer (IE) 6 knows not to use the old IE box model (where borders and padding are included in the specified box width), and the program switches over to the standard model (borders and padding outside the stated width). Thus IE6 and other modern browsers can operate in two different modes: standard mode, and the old rendering style, “quirks” mode.
This decision could not have been easy for Microsoft, considering the number of sites written with IE in mind. I applaud them for doing the right thing, but the job’s only half-finished. Another major behavior variance still exists in Internet Explorer, and it involves that most interesting of CSS properties—the float.
The IE float model vs. the standard float model
To understand the IE float model problem, one must first understand how floats interact with other elements. If you have a block-level element, such as a paragraph, at the top of the body element, it will run from one side of the viewport or browser window to the other.
Now place a left-floated element (a logo image, perhaps) just before that paragraph in the source code. The W3C standards say the block-level paragraph should remain in position, and the floated image should simply overlap it, starting from the upper left corner of the viewport. All recent browsers including IE do this correctly, and it appears something like this:
The dark gray paragraph flows normally, and the preceding blue float is laid over it. The text “line boxes” (shown as white boxes) are not allowed to go behind the float. Instead, they are shortened so as to remain visible.
<body> <img style="float: left; width: 200px;" src="logo.gif" alt="logo"> <p>(a few lines of text)</p> </body>
Please note that the paragraph still stretches all the way across the viewport; the float merely covers part of it. The W3C standards do require that any inline content (like text and non-background images) be kept within the area of the paragraph that is not behind the float. Again, the browsers all get this right.
The trouble occurs when a width is assigned to the paragraph.
The heart of the matter
Let’s say you assign “width: 100%” to the <p>. In a truly compliant browser, nothing would change because that “100%” refers to the total viewport width. Not so in IE.
In that browser, the “width: 100%” is redefined to be whatever horizontal space is available alongside the float, instead of the full viewport width. In addition, the <p> is rendered horizontally starting just to the right of the float. This violates the W3C standards, which require that the <p> begin at the left viewport edge, regardless of any floats that may be present.
To be perfectly clear, any block level element that
- interacts with an external float, and
- has a defined width (or height for that matter)
will show this behavior when viewed in Internet Explorer.
The visible difference is often slight, because the inline content has already been rendered in the open space. With a tall, solid-colored float, it would not be obvious that the <p> no longer slides beneath the float.
In IE the paragraph fills the space next to the float, considering that to be the “width: 100%” given to the paragraph. The <p> stays at this width even below the float.
It gets really sticky when another percentage or unit is used for width.
More than just a little variant
Imagine you’re just starting your hand-coded blog layout. Your idea is to have two separated columns in IE. One method is to float the left column (with suitable margins) and let the following block element run down along the right side of the float.
In IE, assuming the gold float gets a percentage width of 50%, then the following green <p> is set to about 70%. Margins on the float produce two columns, side by side and neatly spaced.
<Body> <div style="float: left; width: 50%;"> (contents of left column) </div> <p style="width: 70%;"> (contents of right column)</p> </body>
When this layout is viewed in a standards-compliant browser, however, the <p> starts at the left viewport edge and runs 70% across the screen, leaving a 30% gap on the right side. Even worse, if the <p> is not wide enough, insufficient space will be available in the portion not covered by the float, and the content within the <p> may force it to extend vertically downward until the float ends. Then the line boxes inside the paragraph can be displayed below that point, spanning 70% of the viewport.
This gives a whole new meaning to the word “variant.”
Margin of error
There is one way around this problem, and that is to apply a left margin on the <p> as wide or wider than the float. That way the float can’t cover it, and the deadly width declaration may be avoided.
<Body> <div style="float: left; width: 50%;"> Float</div> <p style="margin-left: 55%;"> (some text)</p> </body>
Unfortunately, IE has a companion bug involving those line boxes I mentioned before. It seems that if the <p> is not given a defined width, then the line boxes (containing text and images) get shortened exactly 3px. Why? I do not know. I assume that it was done so that no CSS newbie would ever see the paragraph text actually come in contact with the float.
“So what?”, you might be saying. Okay, I’ll tell you. That 3px addition only gets applied when a particular line box is shortened so it won’t go beneath a float, or even if it is level with a float. This means that if you set the margin of the <p> well to the right of the float, the 3px space is still applied, but only to the line boxes directly opposite the float. Thus, at the point where the float ends vertically, the 3px space is no longer applied, resulting in a visible “jog” down the left edge of the text block.
An actual IE5.5 screenshot, blown up to twice normal size in order to clearly display the 3px jog.
The IE “double whammy”
The box model problem may have been more widespread and obvious than the float model problem, but it’s no more damaging to a layout. I can’t tell you how many times I have had to explain these facts to some peeved CSS newbie on the newsgroup I inhabit.
This sort of inconsistency is not good for the standards movement and is the genesis of comments such as, “Browser X shows my pages great. Those other browsers are all screwed up!”
So what’s to be done?
Glad you asked. First, look at it from Microsoft’s point of view. They face the same dilemma they did with the box model problem. If the IE float model is simply altered to match the standard float model, then many sites are going to break in that new browser version.
Fortunately, a workable solution already exists in the form of that handy doctype switch mentioned earlier. It should be quite easy to make the new browser employ the standard float model along with the standard box model by using the proper doctype. At least, I hope it’s easy.
The folks at Microsoft might ask, "What about the sites that have been written in strict mode since the doctype switch was introduced? Won’t they break when the new browser comes out?"
Yes, they will, but, nearly all those sites will have been written by forward thinking, standards-aware coders. Most will understand the situation, and the fuss will be minimal. If these changes are delayed, however, the potential mayhem will increase dramatically.
Perhaps it would be more acceptable to Microsoft if a new doctype was introduced to cover both changes to the CSS model. Such a doctype might be called “ultra-strict” (now we’re talking!). It would be nice if they could fix the 3px line box space while they’re at it.
The box model dragon has been slain. Now it’s time to go after his little brother. Tally ho!
 In this section, it clearly states
that a float “is pulled out of the flow,”
and that line boxes get shortened next to a float. No mention is made of
altering other “normal flow” rules because of the presence of floats.
Back to content
John P. Gallant aka “Big John” is an independent web developer and avid CSS bug hunter. He can usually be found posting to the css-discuss list. Although Web design is only a hobby so far, he has big plans. His CSS related site Position Is Everything details a few odd CSS browser bugs. In his off-time he pedals a mountain bike across the wilds of western Arizona, describing same in Mohave County On The Rocks.