-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Fix menu keyboard access and ARIA labeling for screen readers (Fixes #2155 and #2769) #2897
Conversation
Handle correct keyboard operation of menu, including single tab stop for menu, arrow keys within the menu, focus movement within the menu, and ARIA roles for parts of menus.
Thanks, @OwenEdwards. I'll take a look at it ASAP. |
@gkatsev hold off on pulling this - I need to do more work on the "volume menu button" since keyboard handling may conflict (arrow keys apply to the volume slider, not to moving between menu items). |
Alright. |
@gkatsev that would be nice to have, but I don't see that it's implemented in V5 right now? I thought this was something that was left to videojs-hotkeys "A plugin for Video.js that enables keyboard hotkeys when the player has focus"? I was specifically referring to the fact that a slider handles arrow keys when it has focus, but the ARIA definition of a menu defines that arrow keys move focus between menu items, so there's a conflict. By ARIA standards, the Volume Menu Button isn't really a 'menu', it's a custom widget with a button and a slider. It could even have a single keyboard focus, where arrow keys adjust volume and Space or Enter mute/unmute the player since right now its keyboard interaction is a little confused. |
Didn't know about that plugin and yeah, most of the hotkeys should still be left to the plugin. I think some stuff we probably should have in core. Like Ah, interesting. So, the issue is how apply the ARIA spec to the |
@gkatsev right, that's the concise way of putting it! The volume menu button is a "menu" in VJS, but not a menu according to ARIA, where it's either a button and a slider, or a custom widget. One thing which I'm still not clear about is that, for vjs menus, they open on hover due to CSS, but they also have this handling of click and lockShowing in JS. Do you know, is this to allow a CSS skin to change the onhover/onclick behavior? I haven't been able to track it down, and trying to get everything to work with keyboard-only operation without breaking existing behavior is tricky! ;-) Let's split 'hotkeys' onto a separate GitHub issue - it ties into accessibility, but I don't want to muddy this issue too much! |
I think the |
@gkatsev @mmcc @heff can any of you explain what the For the Captions and Subtitles menus, they seem to do nothing because clicking on the menu button opens the menu (and calls For the As I try to fix keyboard accessibility of controls which are not just a button, issues with this lockShowing functionality are becoming a major roadblock, and I think they're actually usability issues becond keyboard accessibility. What do you guys think? |
I think We probably should change lock-showing to apply when clicking on the menu button and get removed when clicking on it again and not be removed on |
Re: lockShowing...if I remember right it was meant to allow for keyboard triggering of menus. So tab to the menu button, hit space bar to open the menu, tab to the first menu item and menu stays showing. I can't say if that's how it is now, but I think that would be the main use case to confirm is still working if you strip it out. |
Like the discussion here, I think the flaw is with keyboard+mouse interaction. I.e., if you tab into the menu and then mouse over it, it'll be hidden, but should it? We probably would want to know whether we tabbed into the control and only apply the mouseout event if opened the menu with the mouse. |
@gkatsev I think the issue with keyboard+mouse interaction is a bit of a distraction - I'm thinking of control interaction in this order:
I think mouse+keyboard is a concern, but not until we've got those other ones working! So the questions I still feel hasn't been answered is: 1/. Do we want the Captions and Subtitles menu buttons to: a/. Appear on hover (mouse) and on tap (touchscreen), or 2/. Do we want a mechanism for mouse users to open the menu and leave it open after mouseout? 3/. Do we want the behavior in 1 and 2 to be changeable for site creators? Via CSS skin, or via Video.js parameters? The preferred behavior of menus for keyboard-only users (including keyboard-only screen reader users) is defined by the ARIA specs, and should follow most or all of that pattern, but this does not affect the mouse and touchscreen operation of these controls. Then we need to make a decision for the combined volume slider and mute button, in both inline and non-inline/vertical configuration. This does not have to match the menu operation, and the keyboard interaction with this combined control is definitely going to be different from keyboard interaction with the menu. I do think we should split the |
I just realized that I'm doing some of the stuff you already had in here, for example in #2994. I'll go through and de-dupe and make suggestions and what not. |
if (this.selectable) { | ||
// TODO: May need to be either menuitemcheckbox or menuitemradio, | ||
// and may need logical grouping of menu items. | ||
this.el_.setAttribute('role', 'menuitemcheckbox'); |
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.
locally, I've played around with the menu
itself to a role of listbox
and these to a role of option
.
Using ChromeVox for testing it actually produced decent results since it told you how many options and whether they're selected or not.
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.
Not sure if this is a chromevox issue or not, but if I have captions in the list, when I expand the captions menu, it'll read the label of the last caption in the list.
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.
Going to chalk it up to a bug in chromevox.
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.
Don't base your understanding of whether accessibility is working on ChromeVox!!! You'll hurt your credibility with accessibility experts ;-) It's convenient because it's free, but Firefox+NVDA on a PC is a much better free, standards-compliant alternative. See http://webaim.org/projects/screenreadersurvey/.
That said, I've also been looking at some options around listbox
and option
. Semantically, the menus (e.g. the CC menu) are complicated because they have a current state (selected item), potentially a non-actionable title, a settings menu option (which is not "selectable", but is actionable), and a set of options of which one can be picked (we had that discussion about whether more than one could be picked, if we combine CC and Subtitles into a single menu, but I think we concluded they couldn't).
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'll check out NVDA. I've been using OSX's VoiceOver the latter half of last week once I realized that ChromeVox isn't good enough.
Also, to answer the questions in your last comment.
Moving the |
Looks like ChromeVox, while nice for getting an initial idea for things, functions differently than VoiceOver and others. |
Also, I've been thinking that we should just merge this because it's progress towards better accessibility. I have some updates to my PR (#2994) that are based on these changes that hopefully also make it slightly better. |
} else { | ||
this.removeClass('vjs-selected'); | ||
this.el_.setAttribute('aria-selected',false); | ||
if (this.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.
Just a general thought, not necessary for this PR: would we have an easier time with menu-button/menu-item if we started from a <select>
element?
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.
Yes, just using a <select>
should hopefully makes things easier, though, it'll make even less sense to have the caption settings menu button in it then, so, we'll have to put it elsewhere.
Also, <select>
is not styleable at all.
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.
Yes, just using a <select>
should hopefully makes things easier, though, it'll make even less sense to have the caption settings menu button in it then, so, we'll have to put it elsewhere.
Also, <select>
is not styleable at all.
if (event.which === 37 || event.which === 40) { // Left and Down Arrows | ||
event.preventDefault(); | ||
this.stepForward(); | ||
} else if (event.which === 38 || event.which === 39) { // Up and Right Arrows |
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.
If we're going to do keypress handling in a number of different places, we probably should consolidate these character codes.
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.
Yes, yes we should.
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.
Agreed! That was on my list to look at as park of this accessibility work; any thoughts on where it should go? utils/dom.js, perhaps? We need the ESC key from the modal dialog, too.
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've been thinking of grabbing this lib: https://github.com/timoxley/keycode
Seems to be small and tested and does exactly what we want.
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 https://github.com/timoxley/keycode library seems like it would work. Potentially a little overkill (I was thinking of something as simple as the this.keys
array from http://oaa-accessibility.org/example/15/), but why reinvent the wheel??
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 opened an issue for this: #3022
@gkatsev I'm cool with moving forward with this, especially if you have additional fixes in the wings. I'd be curious to hear your thoughts on any of my comments, especially the thought about |
Superseded by #3033. |
Implement ARIA-specified keyboard access to control bar menus (as in http://www.w3.org/TR/wai-aria-practices-1.1/#menu), and ARIA markup to indicate menu role and state to screen readers.
This also fixes #1446 / #1447, which seemed to have come back (or was never actually resolved) as an issue for keyboard access of menus.
This fix depends on #2889.