The Wayback Machine - https://web.archive.org/web/20040806004640/http://www.positioniseverything.net:80/explorer/threepxtest.html

The IE Three Pixel Text-Jog    

This is an IE only effect

Please look closely at the test box to the left. Observe how the text at the top does not quite touch the blue bordered float on the left. The text should touch the float, but instead it seems to have a 3px padding, keeping it away from the float.

Now see how in the black bordered paragraph the 3px space is still there. The left edge of the paragraph is way over on the left edge of the test box (behind the float), but the space is still evident. This implies that the space is connected to something in the <p>, not the <p> itself.

But just what is in the <p>?

Only text, which also means 'line boxes'; invisible 'anonymous' boxes that contain inline text, images, and anything else that is declared 'inline'.

So apparently IE is adding 3px of space to the end of the line boxes in this demo if they touch the float. Now cast your eyes down to the bottom of the test box. Observe how the 3px space is evident even tho the red bordered box (#jog-box) is left margined far enough to separate it from the float. This means that the added 'space' is applied to the line boxes that are adjacent to a float, not just to ones that are touching the float.

Here's the tricky part

Observe how the 3px space abruptly ends at the same vertical height that the float also ends. (!) It's now clear that the float is causing the 3px space to be added to the line boxes. In fact, if the blue box were floated to the right, the space would be appended to the right end of the line boxes.

The close-up image at the lower left shows the 'text-jog' that results when the float is passed by. It is this 'jog' that is the main problem, causing a small but irritating blemish on otherwise flawless layouts.

Another problem may occur in tightly fitting layouts when the 3px space is added. Say you have a float followed by a div holding a large image. Both the float and the div are in a container, and the width of the div combined with the side margin on the div equals the container width.

When the adjacent float induces the 3px space on the one big line box inside the div (the one holding that image), the div can no longer fit in the container! That's because there is 3px of new width on the div, but IE has already determined box widths, and refuses to go back and redo it. So what happens is that the div does not display until it is below the vertical level of the float. There, the 3px does not get applied, and the now properly sized div fits just fine.

Without knowledge of the 3px space, solving this misalignment can be nearly impossible.

Now it can be fixed!

Up until late 2003 it was thought that there was no good way to prevent the jog, but now I'm proud to introduce a new method of curing this long time irritant. It involves supplying the paragraph with a stated dimension, either 'width' or 'height', which prevents IE/win from adding the 3px space.

Unfortunately, this dimension also throws IE into its proprietary float model, detailed on this page. In effect, when the dimension is applied, the paragraph seems to act much like a float, displaying next to the real float, rather than letting the float drape across it.

Normally this behavior must be avoided to keep all the browsers in agreement, but thru hackery it can actually be employed to kill the 3px jog while not leading to variance. How's it done? Dig this.

The Holly Hack

Giving the paragraph a 'width' leads to unacceptable difficulties, but 'height' does not have this problem. The question is how to do it. Simply assigning a height to the paragraph won't work, because any change in content, resolution, or screen width will cause empty space in the paragraph, or worse, overflowing text.

But, since only IE really needs this height, it can be fed only to IE via the Tan hack. "What good is that?" I hear you say. Well, it so happens that IE/win has another misbehavior that makes it enlarge a box (usually vertically) to keep content inside the box, even when the box is stated to be shorter!

Such non-standard behavior can play havoc with advanced float layouts, but in this case it comes in real handy. Have you guessed it yet? If not, here it is. Just give the paragraph a very small 'height' such as 'height: 1%'. See what happens now? IE sees that height and puts the paragraph next to the float, killing the 3px jog. And, since the content is certainly taller than 1%, the box is made taller to accomodate it! One bug sent to kill another. Woohoo! (kudos go to Holly Bergevin)

Details

Remember, only IE/win is allowed to see this, and in addition, IE shouldn't see the left margin on the paragraph. That left paragraph margin actually is allowed to run behind the float (as it should), but the paragraph box itself is kept from doing the same when it has that dimension (very wrong). In addition, that paragraph margin seems to get 3px added to it by IE, so if the margin is as wide or wider than the float, this 3px variance will make IE have a wider gap between the float and the paragraph.

Special Note: This fix should be used on a wrapper element enclosing all content following the float, not on individual elements. By applying the fix on just one big element the hack stays simple and possible problems are avoided.

Rather than deal with this madness, just apply desired horizontal space between the two elements by using a right margin on the float instead of the left margin on the paragraph. Here's how it might look in code:

#floatbox {
  float: left;
  width: 100px;
  }
 
p {
  margin-left: 110px;
  }
 
/* Hide from IE5-mac. Only IE-win sees this. \*/
 
* html #floatbox {
  margin-right: 10px;
  }
 
* html p {
  height: 1%;
  margin-left: 0;
  }
 
/* End hide from IE5/mac */

Two more things. When the IE float model is invoked, the float suddenly has a 3px margin on the paragraph side, which at least can be killed within the Tan hack either by a negative 3px margin, or by reducing the existing float margin by 3px.

Additionally, as mentioned before, IE5/mac must be kept from seeing the hacks, so the hacks are wrapped in the Mac-hack (uses comments). See this live demo for a working example of this method, and check out the source for tips.

Special Note: If the float is an image (or presumably, other generated content), then the 3px line box space is NOT applied by IE. Sadly, IE5.x/win does not leave it at that, but in the event of a floated image, a proprietary 3px margin is applied to both the left and right sides of the image.

Unlike the 3px line box space, these unfortunate margins can be hacked away by use of the Tan hack, thus:

* html #floated-image {
margin: 0 -3px; ma\rgin: 0;
}

Using '* html' before the target element keeps all but IE from recognizing it as a real selector. IE thinks there is a wrapper element surrounding 'html' and so does obey all rules within this block. The second 'ma\rgin' is ignored by IE5.x/win, so IE6 and IE5/mac get the non-hacked margin values. For more on the Tan hack see this page.

Conclusion

IE is still a big headache, but I personally thought this problem would never be solved. Glad to see that not all is lost.

Thanks to Ellen Herzfeld for timely testing of various Explorer versions.


Holly 'n John   Contact me ©positioniseverything
Last updated: December 14, 2003
Created January 18, 2003

Float
This text touches the blue float directly, and has the 3px space on the left.

This text is wrapped in a paragraph (black border), and see, the space is still there, deep inside the <p>!

This box is margined on the left, the width of the float and more, to keep it separate from the float. Still, the space continues, until.. hey! Where'd it git to?! Well, it appears that: no adjacent float, no 3px space.