So, I’m spending part of my Friday at work like I usually do, working on prototype applications or product ideas I have. I’m working inside my XML Editor (OxygenXML 8) to validate my layout and I hit the pretty print button. All hell breaks loose with my layout. Firefox and Safari both render the layout exactly the same in the broken version, which told me that it probably wasn’t a “bug” but a misunderstanding of the spec on my part.
Here’s a sample of what happened. I went from this:

to this:

After several hours of close reading, double-checking everything, and generally pulling my hair out, I found out that the problem is that the XML editor turned an empty div in my code into an empty XML element. In other words, the only change to the source was from:
<div class="someText">an item</div>
<div class="toBeFilled"></div>
</div>
to this:
<div class="someText">an item</div>
<div class="toBeFilled"/>
</div>
All of this stems from the fact that XHTML uses XML semantics without a real XML parser. The bottom line is that unless the element is defined in the XHTML DTD as EMPTY, you shouldn’t use the empty element notation. It’s better and correct to leave it as separate open and close tags. Many developers have run into similar issues with the script tag, which also has some weirdness when used in the empty element notation. This is why, apparently, browsers do this. I don’t know if they handle it well, though.
Continue reading if you want more information and some links on the background for this.
The weirdest thing was how Firefox interpreted the empty element div. Take a look at this screenshot of my Firefox with Firebug activated. Firebug displays the current DOM as Firefox sees it after all the JS, CSS, etc. is interpreted.

Take a look at the two arrows. Leaving that div as an empty element in the first item causes everything after the first singleItem to be nested inside that element. In other words, the empty element notation gets interpreted as a start tag and nothing more. Boo.
This is what it should’ve looked like:

It’s an interesting choice and probably complicated by the need to be backward compatible, plus the fact that I’m serving the page as text/html instead of one of the explicity XHTML mime types, plus general vagueness in the spec.
Here’s the source file for the examples used: Sample source code. I was changing line 44 to reproduce the results above.
If you’re interested in learning more, the relevant portions of the XML spec and XHTML spec provide some insight. Also, I found this good explanation of the origin of the empty element confusion. SGML, XML, and HTML all running into each other… wonderful.
Hope someone finds this useful, because no one should lose 2 hours of their life to weird HTML bugs.
Update: A colleague at work points out another good overview of the weirdness at Ajaxian.





June 18th, 2007 at 12:47 am
XHTML and Empty Tags…
I have been working on the MyEPICS 2.0 framework for creating a website to match roommates together. During this time, I was switching from the old layout, to a different look and feel. When the designing and implementing the MyEPICS framework, I tri…