-
Notifications
You must be signed in to change notification settings - Fork 236
fix(menuitem): improve a11y of selected items with aria-current #5888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(menuitem): improve a11y of selected items with aria-current #5888
Conversation
🦋 Changeset detectedLatest commit: 7b19176 The changes in this PR will be included in the next version bump. This PR includes changesets to release 78 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📚 Branch Preview🔍 Visual Regression Test ResultsWhen a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
Deployed to Azure Blob Storage: If the changes are expected, update the |
caseyisonit
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gorg
Rajdeepc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good fix!! One thing was to test that updateAriaSelected() is also called whenever the selected property changes which I see it is happening on
if (changes.has('selected')) {
this.updateAriaSelected();
}|
|
||
| #### Roles and ARIA attributes | ||
|
|
||
| When a menu item with `role="menuitem"` is selected, the `aria-current="true"` attribute is automatically applied to indicate the current item to screen reader users. This ensures assistive technology properly announces the selected state of menu items. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The appropriate way to indicate a selected state for an item in a menu is to use either role="menuitemcheckbox" for multi-selectable items, or role="menuitemradio" for mutually exclusive selection, with the aria-checked attribute to indicate the selected state. An element with role="menuitem" does not support the aria-checked or aria-selected property. See the supported states and properties for a menu item: https://w3c.github.io/aria/#menuitem.
An menuitem can support aria-current, but only in an appropriate context. See https://w3c.github.io/aria/#aria-current, which explains appropriate usage of aria-current:
aria-current state
Indicates the element that represents the current item within a container or set of related elements.The aria-current attribute is a token type. Any value not included in the list of allowed values SHOULD be treated by assistive technologies as if the value true had been provided. If the attribute is not present or its value is the empty string or undefined, the default value of false applies and the aria-current state MUST NOT be exposed by user agents or assistive technologies.
The aria-current attribute is used when an element within a set of related elements is visually styled to indicate it is the current item in the set. For example:
- A page token used to indicate a page within a set of pages, where the element is visually styled to represent the current page.
- A step token used to indicate a step within a step-based process, where the element is visually styled to represent the current step.
- A location token used to indicate the element that is visually styled as the current component, such as within a flow chart.
- A date token used to indicate the current date within a calendar or other date collection.
- A time token used to indicate the current time within a timetable or other time collection.
Authors SHOULD only mark one element in a set of elements as current with aria-current.Authors SHOULD NOT use the aria-current attribute as a substitute for aria-selected in widgets where aria-selected has the same meaning. For example, in a tablist, aria-selected is used on a tab to indicate the currently-displayed tabpanel.
Note how the WAI-ARIA spec explicitly states that "Authors SHOULD NOT use the aria-current attribute as a substitute for aria-selected in widgets where aria-selected has the same meaning."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me rework this to come up with a solution that better fits how you're seeing the solution!
| if (role === 'menuitem') { | ||
| if (this.selected) { | ||
| this.setAttribute('aria-current', 'true'); | ||
| } else { | ||
| this.removeAttribute('aria-current'); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to keep aria-current as a separate concern from selection.
role is determined by either the role on the containing sp-menu or the selects property on the parent sp-menu or sp-menu-group. If the selected state is indicated on a menuitem without selects="multiple", selects="single" or selects="inherit" on the parent sp-menu or sp-menu-group, we should maybe change the role for the sp-menu-item to menuitemcheckbox. This gets messy though, because then the question becomes, what then is the role for the unselected state, and how do we indicate that an unselected item is selectable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@majornista ah- thank you! I did see the note in the W3C docs about not substituting aria-current for aria-selected, but the ticket specifically called out aria-current as the solution, which is why I went this route.
- for role="menuitem", set aria-current="true" if selected, but do not add aria-current="false" if not selected as it's unnecessary
c9506a5 to
7b19176
Compare
Description
Added
aria-currentattribute logic tosp-menu-itemelements to improve accessibility for screen reader users. When a menu item withrole="menuitem"is selected, it now setsaria-current="true". When not selected, the attribute is removed (not set to "false") following ARIA best practices.Motivation and context
This change addresses a WCAG 4.1.2 (Name, Role, Value) accessibility violation discovered during an accessibility audit. Screen readers were not announcing the selected state for menu items with
role="menuitem", causing confusion for users relying on assistive technology.When a menu item was selected, screen readers would only announce "Deselect 1 of 6" without indicating the item's selected state. This particularly impacts users without vision, with limited vision, and those with cognitive disabilities who rely on complete state information for navigation. Now, the screen reader should announce "Deselect, current, 1 of 6."
Related issue(s)
Author's checklist
Reviewer's checklist
patch,minor, ormajorfeaturesManual review test cases
Screen reader announces selected state for menuitem
i. In the bug ticket, they are specifically using NVDA on a Windows machine, so I was using AssitivLabs during development.
aria-current attribute is correctly applied
sp-menu-itemwithrole="menuitem"in browser DevToolsaria-current="true"attributesp-menu-itemwithrole="menuitem"aria-currentattribute (not set to "false")selectedattribute from the first item.aria-currentattribute is removed.Other menu item roles are unaffected
role="menuitemradio"androle="menuitemcheckbox"aria-checked(notaria-current)role="option"in a listbox contextaria-selected(notaria-current)New unit tests pass in CI.
New documentation for menu item is technically and grammatically accurate and follows Spectrum content standards.
Device review