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.

A fieldset of address fields labeled “What is your address” followed by a blue circle exclamation mark icon, which has been triggered to show a blue-bordered box with the text “It’s no use lying. We’ll just follow you home from the cafe. Save us both the hassle.”
I may have haphazardly assembled and then bastardized Gov.UK design system components in browser dev tools to make that screen shot. I only note this because someone may recognize it and it’s important for me to say that the design system does not suggest nor allow this thing I have made.

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

No comments? Be the first!

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>