diff --git a/main.scss b/main.scss index 874ce97..fca35d6 100644 --- a/main.scss +++ b/main.scss @@ -32,5 +32,17 @@ $o-video-is-silent: true !default; height: 100%; } + .o-video__live-region { + position: absolute; + clip: rect(0 0 0 0); + margin: -1px; + border: 0; + overflow: hidden; + padding: 0; + width: 1px; + height: 1px; + white-space: nowrap; + } + $o-video-is-silent: true !global; } diff --git a/src/js/ads.js b/src/js/ads.js index 006e11a..087b5df 100644 --- a/src/js/ads.js +++ b/src/js/ads.js @@ -290,6 +290,11 @@ class VideoAds { // Currently not used, could be used in an interval // const remainingTime = this.adsManager.getRemainingTime(); } + + // Users with screen readers will lose control of video while advert is playing, + // so we explain why and encourage them to wait with this message. + this.video.liveRegionEl.innerHTML=`Video will play after ad in ${options.detail.adDuration} seconds`; + break; } case google.ima.AdEvent.Type.COMPLETE: { @@ -301,6 +306,8 @@ class VideoAds { if (ad.isLinear()) { // Would be used to clear the interval } + + this.video.liveRegionEl.innerHTML=''; break; } diff --git a/src/js/video.js b/src/js/video.js index d673b48..c04f5b8 100644 --- a/src/js/video.js +++ b/src/js/video.js @@ -212,6 +212,9 @@ class Video { } addVideo() { + this.liveRegionEl = document.createElement('div'); + this.liveRegionEl.setAttribute('aria-live','assertive'); + this.liveRegionEl.classList.add('o-video__live-region'); this.videoEl = document.createElement('video'); this.videoEl.controls = true; this.videoEl.className = Array.isArray(this.opts.classes) ? this.opts.classes.join(' ') : this.opts.classes; @@ -233,6 +236,7 @@ class Video { this.videoEl.autoplay = this.videoEl.autostart = true; } + this.containerEl.appendChild(this.liveRegionEl); this.containerEl.appendChild(this.videoEl); addEvents(this, ['playing', 'pause', 'ended', 'progress', 'seeked', 'error', 'stalled']);