Skip to content

[Bug]: Accessibility: The aria-expanded attribute should always be rendered #580

Closed
@afercia

Description

@afercia

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions