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:
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:
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
.