A lot of chatter around the ol’
<summary> elements lately! I saw Lea Verou recently tweet an observation about the element’s
display behavior and that sorta splintered into more observations and usage notes from folks, including a revived discussion on whether
<summary> should be allowed to contain interactive elements or not.
There are a lot of dots to connect and I’ll do my best here to do exactly that.
Can we change the display of elements nested in the
Super weird! If we crack open DevTools, the user agent stylesheet tells us
<details> is a displayed as a block element.
Notice the required
<summary> element and the two additional
<div>s in there. We can override the
What we might expect is that
<details> now has an explicit height of
40vh and three rows where the third row takes up the remaining space leftover from the first two. Like this:
Ugh, but the third row doesn’t… do… that.
Apparently what we’re dealing with is a grid container that is unable to apply grid behavior to its grid items. But the HTML spec tells us:
And a little later:
The(Emphasis mine, again)
detailselement’s second slot is expected to have its
styleattribute set to “
display: block; content-visibility: hidden;” when the
detailselement does not have an
openattribute. When it does have the
styleattribute is expected to be removed from the second slot.
So, the spec says the second slot — the two additional
<div>s from the example — are only coerced into being block elements when
<details> is closed. When it’s open —
<details open> — they should conform to the grid display that overrides the user agent styling… right?
That’s the debate. I get that
slots are set to
display: contents by default, but jamming nested elements into slots and removing the ability to style them seems off. Is it a spec issue that the contents are slots, or a browser issue that we cannot override their
display even though they are in the box tree? Smarter people can enlighten me but it seems like an incorrect implementation.
<details> a container or an interactive element?
Seems reasonable. The spec sure allows it:
Alright, so we might expect that
<details> is the container (it has an implicit
<summary> is an interactive element that sets the container’s
open state. Makes sense since
<summary> has an implcit
button role in some contexts (but no corresponding WAI-ARIA role).
But Melanie Sumner did some digging that not only seems to contradict that, but leads to the conclusion that using
<details> as a menu probably ain’t the best thing. See what happens when
<details> is rendered without the
It does exactly what the spec suggests when it’s missing a
<summary> — it makes its own:
The first(Emphasis mine)
summaryelement child of the element, if any, represents the summary or legend of the details. If there is no child
summaryelement, the user agent should provide its own legend (e.g. “Details”).
Melanie ran that through an HTML validator and — surprise! — it’s invalid:
<details> requires the
<summary>. And when
<summary> is missing,
<details> creates it’s own, though it’s relayed as invalid markup. It’s all hunky-dory and valid when
<summary> is there:
All of which leads to a new question: why is
<summary> given an implcit
button role when
<details> is what appears to be the interactive element? Perhaps this is another case where the browser implementation is incorrect? Then again, the spec does categorize both as interactive elements. You can see how utterly confusing all of this becomes.
Either way, Melanie’s ultimate conclusion that we ought to avoid using
<details> for menus is based on how assistive tech reads and announces
<details> that contain interactive elements. The element is announced, but there is no mention of interactive controls beyond that until you, er, interact with
<details>. Only then will something like a list of links be announced.
Besides, content inside a collapsed
<details> is excluded from in-page searching (except in Chromium browsers, which can access the collapsed content at the time of writing), making things even more difficult to find.
<summary> allow interactive elements?
That’s the question posed in this open thread. The idea is that something like this would be invalid:
<details> <summary><a href="...">Link element</a></summary> </details> <!-- or --> <details> <summary><input></summary> </details>
The link is not discoverable at all to JAWS when navigating with its virtual cursor. If navigating to the summary element via the Tab key, JAWS announces “example text, button” as the name and role of the element. If hitting Tab key again, JAWS again announces “example text, button” even though keyboard focus is on the link.
There is more I could go on about with the various problems different AT have with the content model for summary… but that would just extend this comment out beyond what is necessary. tldr; the summary content model produces very inconsistent and sometimes just flat out broken experiences for people using AT.
Yet, it’s valid HTML:
Scott goes further in a separate blog post. For example, he explains how slapping
<summary> might seem like a reasonable fix to ensure it is consistently announced by assistive tech. That would also settle the debate over whether
<summary> should allow interactive elements because buttons cannot contain interactive elements. The only problem is that Safari then treats
<summary> as a standard button, which loses its
collapsed states. So, the correct role is announced, but now its state is not. 🙃
Where do we go now?
Are you scared to use
<summary> with all of these issues and inconsistencies? I sure am, but only insofar as to make sure that what’s in it provides the right sort of experience and expectations for users.
I’m just glad these conversations are happening and that they’re taking place in the open. Because of that, you can comment on Scott’s three proposed solutions for how the content model for
<summary> is defined, upvote his tickets, and report your own issues and use cases while you’re at it. Hopefully, the better we understand how the elements are used and what we expect them to do, the better they are implemented.