Legend not such a legend anymore(edit)

Lately I decided I was going to recreate the interactive features of the details element using JavaScript (apparently the same day as fellow Brightonian Jeremy Keith).

However I ran in to some very serious issues with the tag combined with the legend element, so serious, in it's current state, it's unusable.

This article has been cross posted from HTML 5 Doctor.

Overview of the details element

The details element, by default, is a collapsed element whose summary, or label, is the first child legend (if no legend is used, the UA provides a default, such as "Details"), with a triangular button to indicate it's current open state.

If you include the open attribute, then the element is open by default. In theory, you could attach a click event to the legend, and switch the open attribute.

The markup would roughly be this:

<details open="open">
  <legend>Terms & Conditions</legend>
  <p>You agree to xyz, etc.</p>
</details>

Here's the details test page I was working from: HTML 5 details test

The issues

The biggest problem, and the show stopper for me, is that the browser's treatment of the legend element completely breaks this markup pattern - this is true for all the major browsers: Opera, Safari, Firefox and IE (tested in all the latest and some older browsers). I'll go in these issues in detail in a moment.

Other problems include:

  • Styling the legend element is exceptionally difficult, particularly positioning
  • Using the WHATWG guidelines to styling the details element prove both difficult to interpret and difficult to implement.
  • When using CSS to style the open state of the details element using: details[open] { height: auto; }, meant that once I changed the open state using JavaScript, it wouldn't trigger the browser to redraw (as it would if I had added a class). I've run in to this before, CSS 2.1 is styling source, not the DOM.

Legend treatment

Surprisingly Firefox is the worst one out in these issues, the rest of the browsers have fairly same treatment of the issue. In the screenshots, I've included a fieldset and nested legend for reference.

Internet Explorer

Both IE7 & IE8 closes the legend element it encounters when it's not inside a fieldset element and move it's contents out to an adjacent text node.

What's also strange, is that looking at the DOM it also creates another empty(?) closed legend element after that text node. It doesn't have any effect, but just looked odd:

IE's details element treatment

Opera

Opera (9 & 10b) is very similar to IE in it's treatment of the legend in the details element, except it doesn't create the second closing legend node. It just closes the legend, and creates the adjacent text node.

Safari

Safari simply strips the legend all together out of the DOM. So much so, that if you open the web inspector, then the error console, you'll see it warning out that it's encountered an illegal element, ignoring it, then encountering the closing tag, so it ignores that too. You're left with just the text node.

Firefox

The best for last. Firefox goes one step beyond the other browsers. It assumes you've forgotten to include the fieldset element. So when it hits the legend element, Firefox inserts an opening fieldset up until it finds (I believe) the closing fieldset element, which obviously it doesn't so the result is the rest of the DOM, after the first illegally placed legend ends up eaten by fieldset element, which leaves my DOM in a mess:

Firefox details treatment

Impact on other elements

details isn't the only element that reuses the legend element for labelling, the figure element also is supposed to support the legend element. The result is obviously going to be the same.

Conclusion

We can't style the legend element when the text is being thrown out by all the browsers, and Firefox's DOM mangling is just too painful to look at.

This basically means that we can't, in any reasonable amount of time, use the legend element inside both the details and figure element in the spec's current state.

For me, I'll be using an alternative element, probably just a p element styled to look like a legend, but that's really not the point. Ideas anyone?

It turns out we weren't the only ones looking at this and Ian Hickson has responded on the issue:

My plan here is to continue to wait for a while longer to see if the parsing issues can get ironed out (the HTML5 parser in Gecko for instance solves this problem for Firefox). If we really can't get past this, we'll have to introduce a new element, but I'm trying to avoid going there.

It's fine to think that Gecko will update, but it's IE that I'm worried about, they won't turn out their render engine, and the result is we'll have to avoid using the legend in any element other than fieldset.

Comments

comments powered by Disqus