IE Hates Fieldsets

As I work on refreshing our primary suite of web-applications on top of modern web-technology, I’m trying to replace our existing table-based form layouts with a more descriptive layout based on fieldsets. However, I’m having a hell of a time with Internet Explorer (I’ve been testing in 7 and 8, though I’m sure 6 has these issues, but luckily, most of our users are on at least IE7 by now).

First big issue, is that IE doesn’t render the CSS for Legends correctly. This has been documented before, but I have a few extra takes on it. One of the things I’m trying to do with my fieldsets, is have one large banner along the top, but no other borders. The CSS looks like this:

fieldset.ronetForm 
{
    border: none;
    border-top: solid 30px #d9e1e8;
    width: 99%;
}

fieldset.ronetForm legend 
{
    background-color: #d9e1e8;
    font-weight: bold;
    text-align: left;
    vertical-align: middle;
    line-height: 30px;
    padding: 0px 5px 0px 5px;
    border: solid 0px #d9e1e8;
}

This will result in a 30 pixel medium gray border along the top that the legend (fieldset title) will sit in cleanly. Here is what it renders like:

  • Firefox - Fieldset Posts - Firefox Legend Rendering
  • IE 7 - Fieldset Posts - IE7 Legend Rendering
  • IE 8 - Fieldset Posts - IE8 Legend Rendering

My favorite part is that the code renders better in IE7 mode than IE8 mode. In order to get the fieldset to render the same in IE7 and IE8, I had to modify the CSS for this:

fieldset.ronetForm 
{
    border: none;
    border-top: solid 30px #d9e1e8;
    width: 99%;
}

fieldset.ronetForm legend 
{
    background-color: #d9e1e8;
    font-weight: bold;
    text-align: left;
    vertical-align: middle;
    line-height: 30px;
    margin: -30px 0px 0px 0px;
    *margin-top: 0px;
    padding: 0px 5px 0px 5px;
    border: solid 0px #d9e1e8;
}

html:not([dummy]) fieldset.ronetForm legend
{
    margin-top: 0px;
}

First, I move the top-margin on the legend up 30 pixels, then reset it using the ‘star’ hack for IE7 and below, and then use the html:not hack (which works for all non-IE browsers I’ve tested) to reset the margin for non IE browsers. One-hundred and twenty bytes added because of a rendering bug. Awesome. What’s worse, there is no way to get rid of the white border between the fieldset’s border and the legend. At least, not that I can find. If anyone has a solution to this, I’d really appreciate it. For now, I’m probably going to have to do special styling for IE, because those white margins are really distracting.

There is, however, another issue I’ve run into with IE and how it handles fieldsets. In my JavaScript, I periodically want to put a paragraph at the top of a fieldset. For fieldsets, the W3C standard does require that the legend be the first non-text dom child of the fieldset. This is a little silly, because this is valid HTML 4.01 Strict:

<fieldset>
 Text in Fieldset
 <legend>Title of Fieldset</legend>
 <p>Content of fieldset</p>
</fieldset>

But this is not:

<fieldset>
 <p>Text in Fieldset</p>
 <legend>Title of Fieldset</legend>
 <p>Content of fieldset</p>
</fieldset>

I’m pretty sure this is to allow for the whitespace text elements that the DOM insists on adding between nodes if you have any formatting in your document, which incidentally is one place where I completely agree with IE breaking away from the standard. I don’t need whitespace only DOM nodes all over my DOM.

But! How is this rendered?

  • Firefox - Fieldset Posts - Firefox Content Rendering
  • IE 7/8 - Fieldset Posts - IE Content Rendering

So, since it occurs before the Legend, IE puts it outside the legend, and Firefox (and WebKit and Opera) all put it inside the legend. Now, this is non-compliant HTML. So, the browser is entering a failure mode to render it, so it’s hard to say that what Internet Explorer is doing here is wrong. However, when the browser enters a failure mode, I would generally expect the browser to try to do what I intended, even if I was doing the wrong thing, so I would say that IE does the incorrect thing here. Honestly, I think that HTML 5 should be relaxed to allow the legend tag to occur later in the DOM, but currently the spec calls for the legend before any flow content.

As I said, I ran into this problem while working on JavaScript. I was trying to use YUI3’s Node utility to prepend my newly created paragaph to the fieldset in question. A more complete version of this can be viewed in this gist.

Y.get('#test_element').prepend('<p>This is new content.</p>');

As demonstrated above, in IE, this is going to render outside the fieldset, not what I intended. So, I had to use the insert command. Incidentally, the insert call does not work quite as documented. I’m reporting it as a bug, and will likely hack together the support, but anyway, I can do exactly what I want as the tool stands.

Y.get('#test_element legend').insert('<p>This is new content.</p>', 'after');

Fieldsets are a tricky situation. Their use is more semantic, and they can create some nice form layouts when used and styled correctly, but Internet Explorer’s rendering of them has so many problems, which IE8 either failed to fix or actually made worse. I still recommend using fieldsets, though what you’re capable of doing stylistically is a lot more limited than it should be. With any luck, this issue will be addressed by Microsoft before the next release of Internet Explorer.