Conversation
lemmyadams
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #232
Fixes #297
Both menus are unusable by keyboard, but for two different reasons, so this is one PR rather than two.
Captions and chapters. MediaElement leaves the visually-hidden
.mejs__offscreenclass applied to the menu while it holds focus, so a keyboard user tabs into a live list of radios and arrows through real options with nothing on screen. Thefocusouthandler re-adds the class in asetTimeout(…, 0), so moving between options firesfocusoutthenfocusin—focusinremoves the class and the queued timeout puts it straight back. That is the flicker described in #232. Upstream: mediaelement/mediaelement#2949Speed. This one is not
.mejs__offscreen— MediaElement does remove that class onfocusin. The menu is hidden byvisibility: hiddenin our vendored plugin-speed.less, revealed only on.mejs__speed-button:hover.visibility: hiddenalso makes the radios unfocusable, so the speed options cannot be reached by keyboard at all:document.activeElementstays onbodywhen you try. A clip-only override does not fix it; the rule has to setvisibility: visible.Fix
focusinhandler is trying to do.Affects WCAG 2.1.1 Keyboard (A) for the speed menu, and 2.4.7 Focus Visible and 2.4.11 Focus Not Obscured (Minimum) (AA) for all three.
Notes on the approach, since a few of the choices are deliberate:
:focus-withinhooks the button, not the selector. On the selector it can never fire for speed, becausevisibility: hiddenstops focus getting inside to trigger it..mejs__offscreen. That class is added and removed by racing handlers, so the reveal must hold whichever way the race lands..mejs__offscreencontributes are undone. Width, border, overflow and the negative right margin that centres the captions menu come from the more specific.mejs__captions-button > .mejs__captions-selectorrule and still apply — resettingmarginwholesale would break the centring..mejs__captions-button-toggleis excluded. In that mode MediaElement still builds the list (addTrackButtonruns before the mode branch) but binds no handlers to it, so a blanket reveal would surface an inert menu.overflow: hidden, so an outline on the label is clipped on the right.:has()is already in use in adapt-contrib-vanilla.Testing
Verified in Chrome on framework 5.56.2. less/ is byte-identical between v7.0.6 and v7.1.0.
Set up a media component with a video that has two or more caption tracks,
toggleCaptionsButtonWhenOnlyOnefalse, andspeedin_playerOptions.features.toggleCaptionsButtonWhenOnlyOnetrue and focus the captions button. No menu should appear — the button is an on/off toggle in that mode.Confirmed by measurement in step 4 that
video.playbackRatefollows the arrow keys (1 to 1.25), and in step 2 that the selected track'sTextTrack.modechanges fromhiddentoshowing.Not covered: screen reader passes with JAWS and NVDA.
Related
mejs-class names that v7 no longer emits, and addaria-expanded, keydown handling anddisplay: none. Post-v7 the interaction itself already works, so none of that is needed.display: nonein particular would make the caption list unfocusable and remove language selection from keyboard users altogether.Two unrelated defects turned up while testing this and will be raised separately: the caption track labels'
forattribute is missing the-btnsuffix present on the inputid, so those radios have no accessible name; and intoggleCaptionsButtonWhenOnlyOnemode the inert caption radios remain focusable.Posted via collaboration with Claude Code