Introduction
Let's talk about lists... While there are many well documented bugs concerning lists in IE, there is one that I couldn't find much about. Basically, in list-items, IE treats block elements with layout like inline-block and in some respect like inline elements, which can cause various positioning and white space problems.
Affected Browsers
The bug affects IE7- and has been fixed in IE8.
Conventions
In the context of this article the terms block element and inline element refer to elements with the CSS property display set to block/inline (explicitly or by browser preset) and not block or inline elements as referred to in html. (E.g. in this article and in CSS a list-item can be an inline or a block element while in html it is always a block element.) Unless indicated otherwise a div is always a block element, spans and images are inline elements.
Block elements are colored green, inline elements are colored yellow.
Road Blocks
When dealing with an IE bug, you're likely to run into a few others that sometimes help solve the problem or, as in this case, hide or disguise it. So to properly observe what's happening, we need to get rid of a few roadblocks first.
As IE positions inline elements with layout differently than ones without, we need to make sure that all inline elements have layout for comparison purposes. Also, rendering of empty elements is faulty in IE, so for this article we'll stay away from those, although the results also apply. Finally if line-height is not explicitly specified, IE shows some erratic behaviour, so line-height is set to '1' for all the example figures. Finally, to make sure abnormalities are not being caused by the list-item white space bug, there is no white space in the code of the list-items.
Example
All we need to reproduce this bug is a list (ol or ul, list-style:none;) with a list-item containing a block level element (e. g. a div) that contains some text. Fig. 1 is a live demo of a list(-item) containing a div with an explicit size, giving layout to the div. Fig. 2 shows a FF screenshot (with the correct rendering) of the above scenario.
List with sized div (live demo)
- T
List with sized div (FF screenshot)
So what's going on?
The ballpark
Well, the short version is, IE doesn't recognize the div correctly as a block element and instead treats it (mostly) as an inline-block.
A closer look
Aligning baselines
To figure out the various effects of IE's misinterpretation, let's start with a sized div that is not overflown by its (inline) content (Fig. 5): First, IE opens a new linebox for the supposed inline(-block) element inside the list-item. Then, the div's bottom is aligned with the bottom of a correctly positioned span (Fig. 4). The span's position is determined by aligning its internal baseline with the baseline of the list-item's linebox which is the excpected CSS behaviour (at least for the span). To mark the list-item's baseline position Fig. 3 shows a list-item containing an image sitting on the baseline. As we can see, the bottom of the text inside the span is perfectly aligned with the bottom of the image.
So to summarize, IE positions the bottom border of the div as if it was an inline element (with layout), then expands the div upward to match the size settings and finally positions the div's content at the top of the div. This baseline alignment behaviour also shows that the block element is not simply treated as an inline-block.
List with image
List with span
- T
List with sized div, no overflow
- T
Overflowing
So far so bad. To make it (even) more interesting let's increase the div's font-size to overflow the div vertically. (Fig. 8) and see what happens. In IE6- the div's box is expanded due to IE's expanding box bug while in IE7 the expected overflow is rendered correctly, but else nothing much has changed: the bottom of the div is still aligned with the span's (Fig. 7) bottom.
List with image
List with span
- T
List with sized div, w/overflow
- T
Overflow alignment
Let's take it one step further and set overflow:hidden on the div. (Fig. 11). Again, IE aligns the bottom border of the div with the corresponding span, the content is positioned at the top of the div, but due to the hidden overflow the box is not expanded and thus the overflow is cut off at the bottom of the div. So it does what it's supposed to do? As always, there's more...
List with image
List with span
- T
List with sized div, overflow:hidden
- T
The End of al(l)ignment
Let's decrease the div's height so it's top border is equal to or below the containing linebox's baseline (Fig. 14) (blowing up the div's font-size would also do the trick). From this point on we can increase the div's font-size (almost) as much as we want and the div won't move... Cool.
List with image
List with span
- T
List with sized div, overflow:hidden
- T
Digging deeper...
Consistencies
When it comes to baseline alignment and it's absence, IE's behaviour with block elements with layout in lists is consistent with treatment of inline elements with layout outside of lists. Note that this does not mean we are talking about valid behaviour, as also outside of the list context the height, width and overflow settings should be ignored when used on inline elements.
To demonstrate, let's place a couple of inline elments in a div with a big font-size. (Fig. 15) (The glyph is inserted to work around yet another IE bug that ironically treats some inline elements as blocks)
Div containing inline elements: glyph, img, span, sized span w/overflow:hidden
TTInconsistencies
Well, I'd love to state that in lists, all block elements with layout are being treated as 'pseudo-inline' elements, but sadly that is only the case for the first block element in a list-item. All block elements that follow, are being rendered correctly (Fig.16).
Further, the whole aspect of the unrecognized block element seems to be restricted to the list context, as inside a div, a block level element is properly treated as such (Fig.17).
List with consecutive, sized divs
- TTT
Div with sized div
Fixing things
Juggling fontsizes
This is rather a workaround than a fix: Drastically decreasing the list-item's font-size sometimes hides the problem (though it doesn't fix it) and does not work if the div's height is too small (compare Fig.14 with font-size:1px;).
Inline list-items
This is a nice fix if there is no need for the list-items to be block elements. Set display:inline for the list-items and all misbehaviour magically disappears.
Floating list-items
Floating the list-items also fixes the bug and may be useful if you need the list-items to remain block elements
How is this relevant?
While it's true that this is not a constellation you might run into easily, this is a problem likely to be encountered when trying to build a vertical navigation using image replacement.

Can I just hilight that last solution, float it left, it was last on your list but what I needed!
Thanks
Comment by Duncan — November 12, 2009 @ 4:48 pm