From e529612e24c7f4410b7dff15f8092c7ecac9ab67 Mon Sep 17 00:00:00 2001 From: Mani Date: Sun, 10 May 2026 15:13:59 -0400 Subject: [PATCH] fix: use aria-live="polite" for descriptions text track display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using aria-live="assertive" on the text track display container caused screen readers to interrupt all other announcements every time a descriptions cue updated. This made audio descriptions inaccessible in practice — users lost context from other page announcements. Change to aria-live="polite" so descriptions are queued and announced without interrupting ongoing screen reader output, per WCAG 4.1.3. Captions and subtitles tracks correctly remain at aria-live="off" since sighted-hearing users relying on those tracks do not need screen reader announcement of caption text. Fixes #7843 --- src/js/tracks/text-track-display.js | 4 +-- test/unit/tracks/text-track-display.test.js | 36 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/js/tracks/text-track-display.js b/src/js/tracks/text-track-display.js index a0dc527505..c4c02e4b6b 100644 --- a/src/js/tracks/text-track-display.js +++ b/src/js/tracks/text-track-display.js @@ -320,8 +320,8 @@ class TextTrackDisplay extends Component { } this.updateForTrack(captionsSubtitlesTrack); } else if (descriptionsTrack) { - if (this.getAttribute('aria-live') !== 'assertive') { - this.setAttribute('aria-live', 'assertive'); + if (this.getAttribute('aria-live') !== 'polite') { + this.setAttribute('aria-live', 'polite'); } this.updateForTrack(descriptionsTrack); } diff --git a/test/unit/tracks/text-track-display.test.js b/test/unit/tracks/text-track-display.test.js index 6dcfb01fc6..b56d3fb6ec 100644 --- a/test/unit/tracks/text-track-display.test.js +++ b/test/unit/tracks/text-track-display.test.js @@ -620,3 +620,39 @@ if (!Html5.supportsNativeTextTracks()) { player.dispose(); }); } + +QUnit.test('aria-live is set to "off" for captions/subtitles tracks and "polite" for descriptions tracks', function(assert) { + const player = TestHelpers.makePlayer(); + const display = player.textTrackDisplay; + + // Stub clearDisplay and updateForTrack so no WebVTT processing occurs + display.clearDisplay = () => {}; + display.updateForTrack = () => {}; + + const tracks = player.textTracks(); + + // Add a captions track and make it active + player.addRemoteTextTrack({ kind: 'captions', language: 'en', label: 'English' }, true); + tracks[0].mode = 'showing'; + + display.updateDisplay(); + assert.strictEqual( + display.el_.getAttribute('aria-live'), + 'off', + 'aria-live should be "off" when a captions track is active to avoid interrupting screen reader announcements' + ); + + // Switch to a descriptions track + tracks[0].mode = 'disabled'; + player.addRemoteTextTrack({ kind: 'descriptions', language: 'en', label: 'English Descriptions' }, true); + tracks[1].mode = 'showing'; + + display.updateDisplay(); + assert.strictEqual( + display.el_.getAttribute('aria-live'), + 'polite', + 'aria-live should be "polite" for descriptions tracks so announcements queue without interrupting other screen reader output' + ); + + player.dispose(); +});