Skip to content
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

Menu component does not expose its options as they receive focus #217

Closed
StommePoes opened this issue Sep 24, 2020 · 3 comments
Closed

Menu component does not expose its options as they receive focus #217

StommePoes opened this issue Sep 24, 2020 · 3 comments
Assignees
Labels
a11y Anything relating to accessibility. bug Things that aren't working right in the library.

Comments

@StommePoes
Copy link

StommePoes commented Sep 24, 2020

Describe the bug
Using a screen reader, while navigating the "Menu" demo component, none of the menuitems inside are read out.

To Reproduce
Steps to reproduce the behavior:

  1. Turn on a screen reader and open a compatible browser (tested combos listed below)
  2. Go to test page https://stommepoes.nl/work/shoelace/shoelace_demo.html OR just the Shoelace demo page for Menu https://shoelace.style/components/menu
  3. Use the keyboard to Tab to the Menu.
  4. "Menu" is heard, however arrowing through the items is silent.

Expected behavior
Menus and menuitems should expose their roles programmatically (announce what they are when focussed), as should the names of each menuitem as they are focussed on. While I don't particularly recommend the code of the W3C example, how a menu should present itself to screen readers can be found here: https://www.w3.org/TR/wai-aria-practices-1.2/examples/menubar/menubar-2/menubar-2.html
(Note: I'm linking to the 1.2 version of the guidelines even though it's Draft. There is a completed 1.1, but for the love of all things holy, don't use that version when looking at combobox patterns)

Desktop:

  • OS: Windows 10
  • Browsers: Edge latest, Chrome latest, Firefox latest, as of 23 September 2020
  • Screen readers: NVDA latest, JAWS 2019.

I'm not familiar enough with web components to recommend fixes for these. Note issue #215 is also applicable to this component.

@StommePoes StommePoes added the bug Things that aren't working right in the library. label Sep 24, 2020
@claviska
Copy link
Member

claviska commented Sep 24, 2020

Thank you for submitting these issues. I'm committed to getting accessibility right, so this is super helpful.

Admittedly, I've never used a screen reader before. I don't have a Windows machine, but it looks like macOS has a utility called Voice Over that may (or may not) be useful to me. I'll try to set it up and see if I can achieve the same results.

"Menu" is heard, however arrowing through the items is silent.

I looked at the W3C example and I don't see any node changes as I move through the options with the arrow keys. I see aria-expanded, aria-checked, but nothing to indicate which item is active.

Looking at the code in menu-item.tsx, I can see where this was a miss. Menu items have an active and a checked state, but only the checked state is dynamic.

<div
  part="base"
  class={{
    'menu-item': true,
    'menu-item--checked': this.checked,
    'menu-item--active': this.active,
    'menu-item--disabled': this.disabled
  }}
  role="menuitem"
  aria-disabled={this.disabled}
  aria-selected={this.checked}
>

I recall reading that aria-selected was more appropriate for what Shoelace calls its "checked" state, but maybe something like this would provide the correct experience.

<div
  part="base"
  class={{
    'menu-item': true,
    'menu-item--checked': this.checked,
    'menu-item--active': this.active,
    'menu-item--disabled': this.disabled
  }}
  role="menuitem"
  aria-disabled={this.disabled}
  aria-checked={this.checked}
  aria-selected={this.active}
>

I'll try to set up Voice Over and test this, but I suspect it won't be as powerful as dedicated screen readers. If there's a good Mac alternative that you'd suggest, please let me know.

@claviska claviska added the a11y Anything relating to accessibility. label Sep 24, 2020
@StommePoes
Copy link
Author

StommePoes commented Sep 24, 2020

Menus are rather complicated in my opinion.

Yours is at least really a plain/open listbox rather than a menu (menus being a set of button+listbox pairs), so you could perhaps follow the listbox pattern rather than menu pattern https://www.w3.org/TR/wai-aria-practices-1.2/#Listbox).

Both rely on actual keyboard focus landing on the elements to cause them to read out, but again I don't grok web components, so the simple act of focussing on something may not magically work as it does in native. The selected state is set with aria-selected="true" (not a boolean attribute, needs the value explicitly) but I didn't think the lack of that is why I'm not even hearing the menuitem values at all.

Even when I saw a checkbox, I never heard that either.

Note for future: With some components such as comboboxes (the fancy-pattern ones like autocompletes, not the fake-select ones), focus remains on the triggering element (input, button, whatever) and a fake-focus is moved around. One method of getting the fake-focus to read out is having a dynamically-changing aria-activedescendent attribute value on the truly-focussed triggering element. Just be aware of that if you make one of those. (edit: listboxes can also use this, it's up to you) Oh and aria-activedescendent has (or had?) issues with VoiceOver, lolz.

You might want to find someone comfortable with VoiceOver for testing stuff on Macs. A developer can play with VO and I don't discourage that, but it's like going from grandma to Powershell: takes some learning. Screen readers are complex software, and not only is there a learning curve for how they even work, there's a separate learning curve of how SHOULD they work and how do USERS use them.

Edit: VoiceOver is considered a "full" and "real" screen reader. It does however have buttloads of bugs compared to the iOS version :)

Here are the bestus combos imho
Windows: Firefox+NVDA, Chrome+JAWS, Narrator (built-in) + Edge. Narrator is still kinda getting up to the level of NVDA and JAWS. When auditing I do also check FF+JAWS and NVDA+Chrome. Both work but sometimes you'll catch discrepancies.
MacOS: VoiceOver+Safari. You can test on Chrome, but some things may still not work as expected. Until very very recently, Firefox was completely silent in VO. Mozilla is still working with Apple on this.
iOS: VoiceOver+Safari (again, Safari preferred over Chrome).
Android: TalkBack+the chrome-like default browser.
Linux: Orca+Firefox. It will nowadays do something with chromium and webkit based browsers but... I stick to Firefox. Orca expects Gnome or a Gnome-based desktop.

@claviska
Copy link
Member

This took a bit of rework and a small breaking change, but it seems to function much better now, at least with VoiceOver. I kept with the menu and menuitem roles but instead of creating a synthetic focus for menu items, I enabled a proper focus which causes them to be announced correctly.

The relevant commit is 5d73537.

Oh and aria-activedescendent has (or had?) issues with VoiceOver, lolz.

Eh, this did seem to [mostly] work but since the menu items are slotted content, it was a pain to generate ids and link between them. It was much easier and better results using a proper focus. 😄

Thanks again for your help with this. I'm very much still learning VoiceOver, but it's already made a huge difference in understanding where and what needs to be corrected in terms of accessibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a11y Anything relating to accessibility. bug Things that aren't working right in the library.
Projects
None yet
Development

No branches or pull requests

2 participants