Menu initial focus does not follow WAI-ARIA recommendations
See original GitHub issueThis is a follow-up to discussion in #16294 with @eps1lon and @ianschmitz, but I didn’t want to add this into a closed issue or merged pull request.
In @ianschmitz’s comment here, there are two issues pointed out that I want to comment on:
- The lack of a roving tabindex
- Focus being placed on the
ul
instead of the first item in the list
Thoughts on roving tabindex
Prior to my overhaul of the Menu focus navigation, it did have a roving tabindex. This was managed using state in the MenuList and had significant performance implications. If the roving tabindex is reintroduced, it should be done purely in the DOM without leveraging state (since using state triggers re-renders of the entire menu on focus changes). I, however, don’t see value in adding the roving tabindex back in for Menu. As I understand it, the purpose of the roving tabindex is so that if you <kbd>tab</kbd> away from a composite widget (see #15597) and then <kbd>shift</kbd>+<kbd>tab</kbd> back to it, your focus location will be remembered. But for Menu, <kbd>tab</kbd> closes the menu and we always want to reset the initial focus location on open of the Menu, so the complexity of the roving tabindex doesn’t seem to add any value.
Reasons for focus being placed on the ul
instead of the first item
This decision was in response to #14483 which voiced the following concern:
Highlighting the first option in the menu can trick the user into thinking it is already selected.
At the time of deciding to change the focus behavior, I looked at a number of desktop applications (including Chrome) and the behavior of opening a menu with focus on the list (i.e. first <kbd>down arrow</kbd> places focus on first item rather than focus starting on the first item) seemed to be at least as common as starting focus on the first item. Also, the Material Design spec didn’t indicate anything one way or the other.
At the time, I was completely ignorant of the WAI-ARIA documentation which clearly states here:
When a menu opens, or when a menubar receives focus, keyboard focus is placed on the first item.
I became considerably less ignorant about the WAI-ARIA documentation while writing up #15597. If I had known then (when I was reworking the menu focus logic) what I know now, I would not have changed the default behavior. I do think the new behavior is reasonable and would be worth retaining as an option (perhaps an initialFocusOnList
property?), but the default should be in accord with the WAI-ARIA documentation.
One of the reasons I was excited to change the default behavior is that it made it easier to support disabled menu items and dividers appropriately, since I didn’t have to worry about the first item being one of those and therefore needing to put the initial focus elsewhere. However, this can be handled in a fairly straightforward manner if this is done in MenuList
leveraging the moveFocus function. So if we continue supporting the current behavior via a property, MenuList
would use the property within its autoFocus effect to decide whether to set focus to the list or call moveFocus to set focus to the first focusable child.
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (7 by maintainers)
Top GitHub Comments
No worries. I wanted to let you know that the Tree View seemed to be fully WCAG AA compliant from my knowledge and was a pleasure to use. Good work to whomever developed that!
I got distracted by the test suite not being able to catch this properly. There are some minor issues to resolve to get a proper a11y test suite for this and then we can work on this. Sorry this takes longer than expected.
I just want to make sure that we have a smooth transition once we get better focus handling primitives from react.