功能焦点:辅助功能
可访问性!您从未了解过的最重要功能。
在 Video.js 组织中,我们努力提供良好的可访问性。与大多数其他软件一样,任何更改都可能以意想不到的方式影响系统。例如,在 Video.js 5 中,MuteToggle
和 VolumeControl
被合并到 VolumeMenuButton
中。虽然这种更改确实使这些控件在视觉上协同工作,但它也做了一些意想不到的事情。它破坏了可访问性。在这篇文章中,我们将回顾哪些功能被破坏了,修复方法是什么,什么是可访问性,以及如何测试并确保其正常工作。
如果您已经了解什么是辅助功能,请随意跳到最后一节。
可访问性?那是什么?
可访问软件支持有视力、听力、运动/灵活性或其他障碍的用户。它还帮助希望使用键盘导航的用户。开箱即用的 Web 应用程序由于 HTML 的特性而具有一定的可访问性,但这仅限于您以预期方式使用原生元素的情况。如果您不能使用原生 DOM 元素,例如 <button>
,而必须使用 <div>
来创建按钮,那么您就需要关注页面的可访问性。
我们无法直接为 Video.js 用户提供听力障碍支持。相反,我们必须通过在视频中添加字幕支持来间接支持这些用户。在 Video.js 中,我们已经支持字幕和隐藏式字幕一段时间了,在内部它们被称为 TextTracks
。事实上,Video.js 自版本 4 以来就支持 WebVTT
格式的 TextTrack
,这更具可访问性。
支持视力障碍用户更困难,但部分在我们的控制范围内。为了支持这部分用户,我们的播放器必须对屏幕阅读器开放。屏幕阅读器是一种将屏幕上的元素读取给用户的应用程序(顾名思义)。除了从屏幕上读取内容外,它还允许用户仅使用键盘或触摸屏上的特定手势与页面进行交互(无需使用鼠标或直接触摸可见项)。HTML 有必须遵循的某些规则,以便页面可访问。我们将在下一节中介绍这些规则的基础知识。屏幕阅读器通过拥有可在视频播放期间读取的描述轨道得到进一步支持。描述轨道是 TextTrack
的一个子类型,如前所述,我们无法自动将其添加到视频中,我们只能在 Video.js 中支持它们。
有关屏幕阅读器列表,请参阅本文末尾的资源部分。
如何使 Web 应用程序对屏幕阅读器可访问?
如果您将原生元素用于其预期目的,那么您大部分工作都已经完成。这就是为什么使用原生元素是使任何内容对屏幕阅读器可访问的推荐方式。例如,如果您使用 <button>
元素,您将获得以下可访问性属性(无需实际在按钮上设置它们)
tabIndex
允许用户通过 Tab 键导航到按钮role="button"
告诉屏幕阅读器这是一个按钮- 空格键和回车键都将按下按钮
在某些情况下,例如在 Video.js 中,将无法使用原生 <button>
元素。您将不得不模仿上面列表中的可访问功能并使用 div
。以下是您必须添加的列表
- 您必须添加
role="button"
属性以将其归类为按钮。 - 您必须添加
tabIndex
,这将允许通过tab
键导航到该div
- 您必须添加对空格键和回车键按下按钮的处理
role
属性值的列表可以在 Mozilla Developer Network 上找到。
在网页的控件和内容上模仿或添加原生可访问性后,下一步是检查 aria
属性。例如,我们为 ProgressBar
滑块使用 aria-live="polite"
。默认情况下,aria-live
设置为 off
,这意味着除非用户取消聚焦并重新聚焦元素,否则不应向用户读取控件的更新。我们使用的 polite
值允许我们将滑块的位置传达给屏幕阅读器,而无需他们改变对控件的焦点。这很有用,因为 ProgressBar
在视频播放时总是更新的。polite
值还会等到屏幕阅读器完成读取其他信息后才传达这些更新。
最后,您需要为元素添加一个可访问的“名称”,以便可以引用它。一个很好的例子可以在 MuteToggle
控件中看到。因为它不是一个简单的“按钮”,我们以一种对大多数用户隐藏但对屏幕阅读器宣布的方式包含“静音”或“取消静音”的 innerHTML
/innerText
。在 Video.js 中,我们将可访问名称和控件执行的操作称为“控件文本”。控件文本在大多数情况下还会更新元素的 title
属性,这对于视觉可访问性很重要。当控件执行的操作改变时,控件文本也会改变。这将允许屏幕阅读器将 MuteToggle
称为“静音切换”而不是“按钮”。它还将传达 MuteToggle
的当前操作。在这种情况下,它将是“静音”或“取消静音”,具体取决于按下按钮时会执行的操作(即按钮的状态)。
以下是 Video.js 中辅助功能的一些示例:
- MuteToggle
<button>
aria-live
设置为polite
,而不是默认值off
。aria-live
的任何非off
值表示innerText
/innerHTML
更新可以发送到屏幕阅读器,而无需用户将焦点移出控件。polite
的值意味着屏幕阅读器应该等到它说完话后再向用户传达这些更新。- 具有“静音”或“取消静音”的控制文本,指示按钮对用户的当前状态
- VolumeBar 滑块
<div>
- 具有
role
属性,值为slider
。例如:role="slider"
- 具有
tabIndex
属性,因为它不是原生控制元素 - 具有监听以下事件的
EventHandlers
- 向上和向右箭头键用于增加音量和滑块百分比
- 向下和向左箭头键用于减小音量和滑块百分比
- 具有
aria-label
属性,值为“volume level”,这是一个可访问的标签,屏幕阅读器将使用它来引用 - 具有
aria-valuenow
和aria-valuetext
属性,这些属性会更新以指示当前音量级别(以便屏幕阅读器可以读取) aria-live
设置为polite
,而不是默认值off
。aria-live
的任何非off
值表示innerText
/innerHTML
更新可以发送到屏幕阅读器,而无需用户将焦点移出控件。polite
的值意味着屏幕阅读器应该等到它说完话后再向用户传达这些更新。
- 具有
问题与解决方案
现在让我们谈谈 Video.js 5 中屏幕阅读器可访问性是如何被破坏的。首先,VolumeMenuButton
在 ControlBar
上取代了 MuteToggle
和 VolumeControl
。VolumeMenuButton
被设置为在点击时模仿 MuteToggle
。它还会在鼠标悬停或聚焦时显示 VolumeControl
。这是一个问题,因为 VolumeControl
现在是按钮的子元素,而按钮不应包含其他控件。对于屏幕阅读器和 DOM
来说,存在两个 MuteToggle button
控件。而视觉上则有一个 VolumeControl
和一个 MuteToggle
。下面您可以看到此行为的 GIF 演示

解决此问题的方法是使用一个普通的 div
来容纳 MuteToggle
和 VolumeControl
。这个普通的 div
将没有角色或控件文本,因此它对屏幕阅读器来说是不可见的。从那时起,我们只需要模仿旧的用户界面。对于那些好奇的人,这个新的 Component
被称为 VolumePanel
。请看下面 GIF 中的新行为

轮廓
控件的另一个重要的辅助功能修复来自于移除了一小段 CSS 规则
outline: none;
我们为什么要这样做?根据社区和外部资源的反馈,我们了解到轮廓应始终保持开启。没有轮廓,就没有键盘焦点在控制元素上的视觉指示,这样,非视力障碍的键盘用户将很难使用这些控件。
总结
希望这篇博文能让您对如何使 Web 应用程序可访问有所了解。如果您发现任何问题或对我们的可访问性或一般情况有任何建议,请随时为Video.js 做出贡献。
如果您想了解可访问性工作的最新状态,请查看PR 和issues 上的 a11y 标签。
资源
以下是一些实际使用的流行屏幕阅读器:
了解更多 Web 辅助功能的资源