Follow-up from #5505
PR #5505 makes the right structural changes to the Text on Media video play/pause controls. Two accessibility improvements were deferred as follow-up rather than blocking that PR.
1. Autoplay assumption creates initial state mismatch
The PR initialises the button as "Pause Video" based on the assumption that videos always autoplay on load. If autoplay is blocked — by browser settings, user preference, or muted-but-blocked autoplay policy — the video won't be playing but the button will say "Pause Video". A user relying on a screen reader or keyboard navigation will press the button expecting to pause, but it will instead start playback.
This is a WCAG 2.1 SC 4.1.2 (Name, Role, Value) concern: the accessible name must reflect the actual current state of the control.
Both APIs support a state check on init:
- Vimeo:
player.getPaused().then(paused => { ... })
- YouTube:
event.target.getPlayerState() in onPlayerReady — returns YT.PlayerState.PLAYING (1) or other states
The fix is to read the actual state after the player is ready and set the button label accordingly, rather than assuming playback started.
2. Consider aria-pressed for toggle semantics (enhancement)
The current approach of changing textContent is a valid way to communicate state — NVDA and VoiceOver will re-read the button name after the change. However, the semantic toggle button pattern uses aria-pressed, which makes the current state programmatically determinable independent of the visible label:
// On state change:
playPauseButton.setAttribute('aria-pressed', isPlaying ? 'true' : 'false');
With aria-pressed, the button name can remain static (e.g. "Toggle video playback") while state is communicated separately. This is the ARIA Authoring Practices toggle button pattern. Either approach is acceptable — this is an enhancement, not a failure.
Acceptance criteria
Related
Follow-up from #5505
PR #5505 makes the right structural changes to the Text on Media video play/pause controls. Two accessibility improvements were deferred as follow-up rather than blocking that PR.
1. Autoplay assumption creates initial state mismatch
The PR initialises the button as "Pause Video" based on the assumption that videos always autoplay on load. If autoplay is blocked — by browser settings, user preference, or muted-but-blocked autoplay policy — the video won't be playing but the button will say "Pause Video". A user relying on a screen reader or keyboard navigation will press the button expecting to pause, but it will instead start playback.
This is a WCAG 2.1 SC 4.1.2 (Name, Role, Value) concern: the accessible name must reflect the actual current state of the control.
Both APIs support a state check on init:
player.getPaused().then(paused => { ... })event.target.getPlayerState()inonPlayerReady— returnsYT.PlayerState.PLAYING(1) or other statesThe fix is to read the actual state after the player is ready and set the button label accordingly, rather than assuming playback started.
2. Consider
aria-pressedfor toggle semantics (enhancement)The current approach of changing
textContentis a valid way to communicate state — NVDA and VoiceOver will re-read the button name after the change. However, the semantic toggle button pattern usesaria-pressed, which makes the current state programmatically determinable independent of the visible label:With
aria-pressed, the button name can remain static (e.g. "Toggle video playback") while state is communicated separately. This is the ARIA Authoring Practices toggle button pattern. Either approach is acceptable — this is an enhancement, not a failure.Acceptance criteria
aria-pressedused for toggle semanticsRelated