Brief Note on Disclosures in Fieldsets
TL;DR: Probably don’t use disclosure widgets in fieldsets. If you do it anyway, don’t put the trigger in the <legend>
.
Context
With <details>
/ <summary>
, recent support for the popover
attribute, and the never-ending belief that a “clean” page means hiding content, there is a resurgence in stuffing useful content behind an interaction.
I’ve already established that you should use <legend>
and <fieldset>
over an ARIA approach. Keeping that in mind, the following image shows a visual design with content behind an interaction.
Technical Bits
The <legend>
element allows phrasing content and heading content. A <button>
is phrasing content, so it can live in the <legend>
.
<details>
is not phrasing content, so it is invalid to use it within <legend>
. Meanwhile, <summary>
must be the first child of <details>
to act as a disclosure, so it cannot live alone within the <fieldset>
and be functional or valid.
The popover
and popovertarget
attributes are new and provide a script-less way of making high-z-index-like toggle-tips. They care little for content type, but the trigger should only be on an interactive control (use a <button>
, please).
Demo
I have made no effort to style any of this other than support for dark mode and the layout. The trigger could look however you want. The spacing is a mess. The layout is meh. This does not use accessible descriptions. This is simply to map AAPI exposure and input modality behavior so you could test for yourself (direct link to demo).
Experience
Anything in the <legend>
is part of the group label. Which means screen readers announce the control name when they announce the group label. The control name and the group label are both announced when landing on the control. If using VoiceOver, it’s announced a second time for Apple reasons. If the disclosure is expanded and its content is also in the <legend>
, well, re-read what I just wrote.
You can skip disclosures altogether and put the text into the <fieldset>
, but a screen reader user may miss it when filling out a form because it’s not part of a group label nor associated with a field. You could use aria-describedby
to close that gap, but it has its own caveats (which are out of scope for this post).
I’m trying not to be prescriptive here. Well, other than telling you not to use invalid HTML and probably never put extra content of any kind in the <legend>
. While I prefer always-visible instructions, there may be cases where a stakeholder wants to hide every bit of useful text on the page. This post exists to provide a caution about the wrong way to do it.
Conclusion
Probably don’t use disclosure widgets in fieldsets. If you do it anyway, don’t put the trigger in the <legend>
.
Leave a Comment or Response