Description
What package within Headless UI are you using?
@headlessui/react
What version of that package are you using?
v1.2.0
What browser are you using?
N/A
Reproduction repository
Your Disclosure demo at https://headlessui.dev/react/disclosure
Describe your issue
First of all, thanks for your hard work on Headless UI!
While using the Disclosure component, our team noticed a behavior related to the aria-expanded
attribute that isn't entirely correct and can be improved for better accessibility.
When the Disclosure is open, aria-expanded
is added to the Disclosure.Button with a value of true
, which is correct. However, when the Disclosure is closed, aria-expanded
is not rendered at all.
I guess this applies also to other components where aria-expanded
is used.
This happens for both the react version and the vue version.
Basically, using an undefined
value makes the attribute be omitted from the DOM:
'aria-expanded': state.disclosureState === DisclosureStates.Open ? true : undefined,
Instead, it should be set to false
.
I do realize that in a react/vue world is pretty common to not render HTML attributes when their value is false
, however aria-expanded
isn't a HTML boolean attribute. aria-expanded
represents a state that is either "collapsed" or "expanded" and it must be always rendered. It also has to do with the way screen readers announce aria-expanded
:
aria-expanded=true
is announced as "expanded"aria-expanded=false
is announced as "collapsed"
Not rendering aria-expanded
when false doesn't provide a correct information to screen reader users: they won't have a clue there's something that can be expanded and it’s currently “collapsed”.
Quoting from the WAI-ARIA Authoring Practices Disclosure pattern, see the "WAI-ARIA Roles, States, and Properties" section:
When the content is visible, the element with role button has aria-expanded set to true. When the content area is hidden, it is set to false.