Wednesday, January 7, 2009

Invalid HTML Does Break Things (<DIV>'s and Lists)...

Everything Looked Fine...

I was working on a project where we were creating a new Wizard for one of our web application. About 2/3's of the way through the screens looked good and everything was working well across all browsers. Then one day I get a Defect Ticket stating that the layout is completely blown out in IE6. The note in the ticket pointed out that X didn't line up with Y (amongst other things).

I looked into it. I fired up the old IE Developer Toolbar and I also looked at the site in FireFox (and FireBug). Even though it was an IE6 issue, I like to also use FireBug/FireFox in parallel in order to get a good lay of the land.

"Hmmm, IE Dev Toolbar is showing my DIV's aren't nested as they should be..."

It took a while to notice this, but, in IE6, the DIV's that contained X and Y were not nested in the Container DIV that they should be. However in FireFox (and IE7), they were. If this was due to an unclosed DIV tag, then all browsers should be screwed up. I did some probing and I found code that resembled the following:

<DL>
     <DIV id="this">
          <DT></DT>
          <DD></DD>
          <DT></DT>
          <DD></DD>
     </DIV>
     <DIV id="that">
          <DT></DT>
          <DD></DD>
          <DT></DT>
          <DD></DD>
     </DIV>
</DL>

Some Clever Developer...

Some clever developer wanted to conditionally SHOW or HIDE different <DT> and <DD> sets, so he wrapped them in <DIV> tags. The problem with that is, according to the HTML 4.1 specification:

Syntax <DL>...</DL>

Contents One or more DT or DD elements...

AHA! This means that a <DIV> cannot be a direct child of <DL>.

When FireFox and IE7 encountered the above code, it dealt with the bad HTML. When IE6 encountered the code, it "read" the improperly nested opening <DIV> but ignored the improperly nested closing </DIV>. The <DIV> was there, but IE6 wasn't acknowledging it because it wasn't properly nested. (It should have ignored the opening <DIV> but it is IE6 after all.)

Fixing the HTML Markup

So how do I fix this without having the developer (in Malaysia) have to rewrite their back-end code. I can clearly see what his intention is, so I modify the HTML Markup as such:

<DIV id="this">
     <DL>
          <DT></DT>
          <DD></DD>
          <DT></DT>
          <DD></DD>
     </DL>
</DIV>
<DIV id="that">
     <DL>
          <DT></DT>
          <DD></DD>
          <DT></DT>
          <DD></DD>
     </DL>
</DIV>

I break up the one <DL> into smaller bits and nest those inside the <DIV>'s. A little CSS tweaking and everything is working, and looking, as intended.