Empty Elements

The blank line in LI elements issue was fixed in Internet Explorer 7 RC1. The remaining issues were fixed in Internet Explorer 8 beta 1.

This refers to elements that have no contents even though they could. It does not mean elements that are not allowed to have contents (such as the <link> or <img> tags). These often occur with generated pages, or may be deliberate so that a script can fill them up later, or they are used incorrectly as spacing elements. Occasionally, they are also used to produce CSS effects.

This is a case of one deliberate mishandling of CSS causing a whole host of mistakes and bugs. Although I do not want to cover accidental bugs in this article, I will cover these, since they are responsible for many sites apparently mis-rendering in other browsers, and also because at their core, they are caused by deliberately not implementing a standard properly.

There are in fact two main issues here. Both HTML and CSS standards specify that if a block element (and some flow level elements) is empty, it should not be rendered at all, unless it has a specified or implied height. So in other words if there is a paragraph that is empty, it should be rendered as if it were never there. However, if it had any margins applied, these should be respected, and added into the vertical margin collapsing.

Collapsing? Ok, I'll try and keep this easy. Two paragraphs. The first has a bottom margin of 10 pixels. The second has a top margin of 20 pixels. The two margins touch each other, so the bigger one is used. Therefore the space between the paragraphs is 20 pixels. This only happens with top and bottom margins.

Ok, now let's expand the idea. Three paragraphs. The first has a bottom margin of 10 pixels. The second has a 30 pixel top margin and a 40 pixel bottom margin. The third has a 20 pixel top margin. Unlike the other two paragraphs, the second one has no contents, so it should take up no height. But its margins must still be taken into account. There are now four margins touching. 10, 30, 40 and 20 pixels. Collapsing takes the biggest one, so the space between paragraphs 1 and 3 (the second is not rendered remember) is 40 pixels.

This may be a difficult concept, but it serves useful purposes, so just accept it. At this stage, we have not lost IE. No, it gets this right up to here. But now lets start making a mess. With IE, if you apply a width to the empty paragraph (usually unintentionally while applying it to all paragraphs), it decides that you want to give it some height too. So it makes it big enough to contain one line of text. Not only does this one line of extra height now get added to the space, but the collapsing is all wrong. So the gap grows to max(10,30) + max(40,20) + line-height, so 40 pixels becomes more like 90. And before you try to use the height style to make it smaller, IE will ignore you. It will still make it one line-height tall, because of its incorrect overflow:visible; handling.

In response, the web developer applies some negative margins or relative positioning, without really knowing what they are doing or why, until the gap returns to normal in IE, about 40 pixels. (This assumes that IE does not decide to cut off the content where a negative margin pushes it over the bounds of its original position.) Of course, this has a very bad effect in the other browsers, as they correctly apply the 40 pixels, plus the negative 50 that was applied for IE, meaning the contents of the two paragraphs now overlap by 10 pixels. Definitely not the intended effect. This is a bit of an extreme example, but the effect is the same, even if a normal margin (or the browser's default margin) is applied to the paragraphs.

Now for the second half of the problem. If the empty paragraph is not given a height or width, it should not be rendered at all, but in fact IE does not do this properly either. It just hides the contents of it, and renders the box as a single invisible line-height box, tucked under where it would have been. Applying a background will show the box in its new position (usually when coupled with a background on a preceding element).

Still not had enough? Ok, let's go for another one then. A more obscure one, but one that many web authors hit when trying to replace JavaScript rollover menus with more accessible CSS styled lists. A list item is flow level, meaning that it may contain block level or inline elements. IE actually ignores the closing </li> tag in these lists. Yes, it ignores it. Meaning that the text after the </li> tag is included inside the LI. If the LI contains a link, and the link has the display:block; style, IE renders any remaining text as a new block, even if that text is just white-space. This is because IE does not correctly implement the flow level display, and does not ignore whitespace nodes when displaying pages. So what else is new?

Demo 1: There is an empty paragraph after this one, with a red background. It has a width defined, but should remain hidden.

Demo 2.1: The next paragraph should have a transparent background (so the grey background behind it should show through)

This paragraph has no background defined.
Any red that incorrectly appears comes from the hidden empty paragraph.

Demo 2.2: The box containing this text has an empty paragraph in it. This should be grey.
Any red that incorrectly appears comes from the hidden empty paragraph.
  1. Demo 4: These links should be the only things in this list. There should be no odd gaps between them
  2. This behaviour is also visible in the main list of links on this page (in IE, of course)

Workaround: To avoid the first problem, never define widths (and a few other styles, clear sometimes also creates the same effect) on elements that have no content - for clears, make them as small as possible using height:1px;overflow:hidden;. To avoid the second problem, never define background colours on elements that have no content. To avoid the third problem, there are a couple of solutions. Remove all whitespace between the </a> and the next <li> tags. Set the display style of the LIs to inline.

Don't click this link unless you want to be banned from our site.