四、理解可访问性 API、屏幕阅读器和 DOM
在本章中,我们将更详细地考虑屏幕阅读器是如何工作的,并看看辅助技术(at)用来访问 web 内容的 DOM 和可访问性 API。理解这一点很重要。虽然有些东西看起来有点抽象或学术,这一章对你构建可访问的 HTML5 内容并不重要,但它会有所帮助。从设计上来说,它也很短。
注如前所述,虽然屏幕阅读器不是残障人士访问网络的唯一技术,但它们无疑是最复杂的。此外,技术可访问性支持需求可能是最广泛的。
如果这一章看起来有点棘手,不要太担心;这不是一个容易的题目。我和残疾人一起工作了将近 10 年,当我作为一名 AT 专家工作时,我有着广泛的辅助技术经验。我很幸运地在现有的各种 AT 以及这些技术的无数应用中获得了大量的经验。
从这个经验来看,我可以诚实地说屏幕阅读器是最复杂的,无论是从可访问 web 内容的作者和 groovy 网站的设计者的角度来看,还是从用户的角度来看。屏幕阅读器熟练程度的范围或水平变化很大,从最基本的“页面周围的选项卡”或“点击全部,看看会发生什么”到虚拟光标的复杂使用、各种内容询问等等。像 VoiceOver 这样的屏幕阅读器的出现,及其对手势和转子的支持,使交互变得更加容易,我们将看到更多手势界面的趋势。然而,目前键盘交互模型过于复杂,用户要记住太多的自定义键盘组合。向移动设备的转移也将减少对键盘的依赖,并专注于更自然的输入形式,如手指滑动和其他手势。
我期待着这些技术的未来迭代,其中的技术调解了复杂性并简化了用户体验。我仍然从向屏幕阅读器用户展示如何用 AT 做新事情中获得快感,AT 用户的数字素养水平之低仍然令我惊讶。AT 用户有时抱怨一些网站或内容无法访问,而实际上障碍是用户无法正确使用他们的 AT。AT 的用户需要学习如何最大限度地使用他们的技术。这是一种双赢的方法,因为用户将从该技术中获得更长的寿命,而卫生服务提供商将获得更低的成本。此外,关注本章将帮助你更好地理解屏幕阅读器如何处理你写的代码。
注辅助技术可能非常非常昂贵,实际上是小众技术。这导致了一种创造性的、自己动手的朋克摇滚文化,这种文化将富有想象力的技术应用融合在通常有限的可用资源中,为残疾人提供解决方案。
定义辅助技术下的元素
当你看到网络内容和 AT interaction 的具体细节时,事情就复杂了。这一章让你对各种平台可访问性 API 之间发生的事情有一个大概的了解,并看看动态 DOM 更新和正确应用语义来描述定制控件。
正如我提到的,我至少花了两到三年的时间来掌握屏幕阅读器的实际工作方式,从研究用户交互模型和熟悉 JAWS 击键到理解幕后发生的事情。这只是从屏幕阅读器的角度来看——不要管数据是如何在各种 API 之间转换的!所以,如果你在海上感到有点失落,也不用担心。这一章是我试图用一种我希望几年前有人为我做的方式向你解释事情。
什么是 API?
一个 API 就是一个应用编程接口。这是一个框架或一组规则,提供用任何给定语言编程所需的代码、函数或词汇。API 可以被认为是一个代码库,你用它来告诉软件,比如浏览器或辅助技术,去做一些事情。
例如,浏览器将以 HTML5 编写的 web 内容转换为文档对象模型(DOM)。网页的这个 DOM 与浏览器使用的布局引擎相关联。然后,浏览器从布局引擎和 DOM 获取信息,以支持操作系统(OS)平台可访问性 API。该 API 允许辅助技术监控和查询浏览器向其公开的任何可访问性信息。
什么是布局引擎?
布局引擎是每个浏览器中的嵌入式组件,它在浏览器中显示 HTML、XHTML、XML 或其他此类内容和格式信息,如级联样式表(CSS)。不同的浏览器有自己的渲染引擎,有自己的显示网页内容的规则。比如 Firefox 用 Gecko 引擎,Internet Explorer 用 Trident,Safari 和 Chrome 用 Webkit 渲染引擎,Opera 有自己的渲染引擎叫做 Presto。
什么是可访问性 API?
辅助功能 API 是特定于平台的 API,可在桌面或浏览器中使用,以辅助技术可以理解的方式传达辅助功能信息。您将编写的 HTML5 代码包含标题、按钮、表单控件等元素。然后,这些元素中的每一个都有一个由可访问性 API 平台定义的角色、状态和属性集(以及与其余文档元素的父/子关系)。
以下是一些主要的可访问性 API:
- 断续器
- UIAutomation
- 苹果无障碍 API
- 不可访问 2
- AT-SPI
注意还有其他可访问 API。例如,如果您正在编写一个 JAVA 应用,并且希望它是可访问的,那么您需要使用 JAVA 访问桥来提供可访问性映射。在 JAVA 中默认是不启用的。
荧幕外的模特(OSM)
在我们更详细地研究 API 本身之前,我们需要后退一点,讨论第一个易访问性模型:离屏模型,或 OSM。它的开发是为了让早期的屏幕阅读器和盲文输出设备能够访问可视桌面和第一个图形用户界面(GUI)。对屏幕外模型的了解将有助于您更广泛地理解这些相关技术是如何交互和表现的。
早期的基于 DOS 的系统,或者命令行界面系统,因为是基于文本的,所以很容易使用。用户输入到系统中的信息,以及系统返回的信息,可以很容易地在内存缓冲区中捕获并合成为语音。这种语音输出是通过使用我在第二章“理解残疾和辅助技术”中谈到的共振峰合成来实现的。文本字符串和数据等字符存储在缓冲区(或内存存储区)中,屏幕阅读器可以轻松地直接访问这些缓冲区,然后以语音形式输出给最终用户。
注这种基本的语音输出被称为 TTS,或“文本到语音”合成。有各种各样的硬件和软件 TTS 引擎。
随着 GUI 的出现,这一切都改变了。然后,控制从通过命令行或基于文本的输入转移到分组为在屏幕上可视显示的相关可选控制(例如菜单和应用控制),以便视力正常的人能够容易地理解。实际上,用户界面被转换成了屏幕上的图形像素,而不是更容易理解的文本。因此,不容易获得原文。因此,需要一种方法来访问来自绘图调用和窗口信息的信息,然后将这些信息转换为像素并存储在屏幕外数据模型中,以便屏幕阅读器可以访问和读取。让它工作是一个非常复杂的操作。为了处理这种复杂性,并提供一种屏幕阅读器以可访问的方式呈现屏幕内容的方法,开发并实现了离屏模型。这是使 GUI 可访问性所需要的一个缺失的环节。
注关于一段非常有趣的屏幕阅读器历史,我推荐 Richard Schwerdtfeger 的论文《让 GUI 说话》,他是 IBM 辅助功能软件组的 CTO,也是著名的辅助功能专家。Rich 还与杰出的 Jim Thatcher 博士一起工作,他开发了第一个 DOS 屏幕阅读器和第一个基于 GUI 的 PC 屏幕阅读器。你可以在
ftp://service.boulder.ibm.com/sns/sr-os2/sr2doc/guitalk.txt
拿到这篇论文。
对于基于 GUI 的系统,离屏模型的工作方式是捕获关于要在屏幕上可视化呈现的控件的信息,然后创建一个单独的页面版本(离屏模型——因此得名)。然后,屏幕阅读器与这个 OSM 交互,并使用其内容作为输出最终用户可以理解的语音的基础。
您可以将离屏模型想象成任何给定时间的屏幕快照。正在发生的是一种被称为屏幕抓取或挂钩图形调用的技术。如今,对于桌面系统,操作系统提供了公开和检索这些信息的工具,但是是应用及其用户界面组件通过 API 公开这些信息。
现代编程语言允许使用对象和元素的描述,屏幕阅读器可以通过可访问性 API 锁定这些描述。然后,当用户通过键盘获得焦点时,屏幕阅读器将这些名称和属性作为语音输出给用户。正如我提到的,对于桌面应用来说,维护 OSM 的需求已经减少,但并没有完全消失,在开发人员忽略了标记控件的语义的情况下,它仍然是有用的。因此,OSM 可能仍然会发挥支持作用,为屏幕阅读器提供尽可能多的信息,从而促进更完整的用户体验。
对于一个操作系统来说,让它变得可访问肯定会带来特殊的挑战,但这些挑战或多或少都被克服了,因为操作系统通常设计良好,是一个更封闭的环境类型。这使得像屏幕阅读器这样的应用的设计变得更加容易,因为良好的编程实践,例如正确标记的控件等等,可以直接集成到操作系统中。那么,什么都可以去的世界互联网呢?
注糊涂了?嗯,有点复杂,不用担心。简而言之,OSM 可以被认为是一个内部数据库,屏幕阅读器在内容呈现到屏幕之前访问它。作为一个有视力的人,你看着浏览器,得到一个页面内容和各种控件的图片,包括它们的功能等等。屏幕阅读器只是从与浏览器相同的来源获得这些信息,但它绕过了视觉呈现,使用代码来导航页面内容并将其输出为语音。
屏幕阅读器如何访问网页或应用上的信息?
如今,并不是所有的屏幕阅读器都主要使用 OSM 来与网络交互。OSM 被视为过时的技术。此外,维护一个 OSM 在技术上很困难,对开发人员来说也是一个挑战。例如,当您第一次尝试自己测试网页时,您可能会发现很难理解屏幕阅读器是怎么回事。你会失去你在页面上的位置,或者发现在某些时候很难知道屏幕阅读器的焦点在哪里。(会发生的。)这有助于理解你首先不是直接与浏览器互动,而是与这个第三位互动。
注意在与 Web 交互时,实际上“第三位置”是 DOM 和可访问性 API 输出的组合——以及一些屏幕阅读器的 OSM。当你第一次接触这些东西时,最初认为它们代表着同样的东西会有所帮助。它们并不相同,但实际上结合起来创造了“第三个位置”所以它作为一个抽象概念是有用的——这样你的脑袋就不会爆炸。
前面我们讨论了像 JAWS 这样的屏幕阅读器在与 Web 交互时使用的各种光标。电脑虚拟光标是 JAWS 用来浏览网页的主要工具。该虚拟光标实际上指向虚拟缓冲区中的内容数据库——实际上是 osm 和 API 调用组合的可用内容的缓存。屏幕上可视化内容的缓冲允许 at 用户浏览屏幕内容。因此,虚拟光标代表屏幕阅读器用户的浏览点,当视力正常的用户浏览网页时,它可能与焦点不匹配。
记住视力正常的用户在浏览器中看到的只是 DOM 内容的可视化呈现,由 CSS 样式化。注意,这不适用于插件,如 Flash 内容或 Java 小程序,或者实际上,HTML5
<canvas>
API。
为了让这个快照与辅助技术一起工作,或者为了让它被认为是可访问的,离屏模型需要被提供良好的语义代码,如前所述。这意味着对可访问性更敏感的开发人员已经以符合可访问性最佳实践的方式标记了页面标题、列表项、表单控件和图形。当您这样做时,OSM 的内容是结构化的,由良好的语义支持。因此,添加你的<h1>
和<li>
以及你的表单输入<labels>
不仅仅是一个深奥的练习,而是创建一个可访问性架构的重要方式,该架构为辅助技术提供了一个用于导航和理解的结构。
您可能还记得我之前谈到过屏幕阅读器使用的表单模式。像 JAWS 这样的屏幕阅读器使用虚拟光标,这样用户可以通过按 H 键、G 键(对于图形)或 B 键(对于按钮)来导航标题,或者在页面上调出链接对话框。这是可能的,因为虚拟光标已经捕获了击键,将它们用作导航控件。那么当你想在网页上输入一些数据的时候呢?显然,您不能同时使用屏幕阅读器的这些导航功能。
记住这就是为什么有像 JAWS 这样的屏幕阅读器的表单模式。在窗体模式下,屏幕阅读器从使用 PC 虚拟光标切换到直接与浏览器交互。这将禁用虚拟光标,并允许屏幕阅读器用户直接在表单中输入数据。
这种表单模式也给 web 开发人员带来了一定的挑战,因为当开发人员在表单模式下工作时,通过 PC 虚拟光标可以获得的重要数据可能不可用。这些丢失的数据可能是关于如何填写表单的说明等等。在表单模式下,应该注意表单验证和更新屏幕内容,这样屏幕阅读器用户就不会错过您需要给他们的指示或反馈,比如丢失输入数据等等。
简而言之,您已经看到了离屏模型的概述,以及 JAWS 等屏幕阅读器使用的一些光标。接下来,我们将查看 DOM,然后深入探讨启发式方法。
提示记住有些屏幕阅读器根本不使用离屏模式。其中包括用于 Mac 的 VoiceOver 和用于 PC 的 NVDA,这是一款优秀的免费开源屏幕阅读器,可以与屏幕阅读器用户系统上现有的一些语音合成包一起使用,如 SAPI4 或 SAPI5。
什么是 DOM?
DOM 代表文档对象模型,以一种树的形式表示网页或其他类型文档的语义结构。如图图 4-1 所示,网页中的各种 HTML 元素组成了树上的叶子,叶子就是元素节点。
***图 4-1。*了解创建 DOM 的 HTML】
图 4-1 所示的节点代表了浏览器或辅助技术将会看到的文档的各种结构部分。DOM 还可能提供关于节点的状态的信息。
正如您在图中看到的,您有一个 header,它包含文档的<title>
,还有一个<body>
,它包含一个作为标题的节点(<h1>
),一个作为段落的节点(<p>
,它有一个作为<a>
的子节点,还有一个作为无序列表的节点(<ul>
,它有三个小小的<li>
)。
注在现实中,用户代理,可能是浏览器或某种辅助技术,在构建 web 文档的图片或模型时有几种选择。它可以直接与 DOM 交互,或者使用离屏模型,或者它可以通过平台可访问性 API 获得关于这些不同节点及其状态和属性的信息。我之前提到过一些可访问性 API,比如 MSAA、iAccessible2、苹果可访问性 API 等等。
可访问性 API 是如何工作的?
可访问性 API 充当浏览器、DOM 和 AT 之间的网关或桥梁。为了让辅助技术能够理解 DOM 的内容,需要将这些内容映射到可访问性 API 中的相应角色。API 就像一个过滤器,帮助在任何给定的时间了解 DOM 中发生的事情。实际的 API 做的不止这些,因为它不是完全静态的。它可以促进用户界面组件和辅助技术之间的动态交互。
记住对于辅助技术来说,可访问性 API 就像是操作系统和网络之间的桥梁。
一个 API,比如 MSAA 或者苹果的可访问性 API,允许屏幕阅读器用户知道一个项目何时有焦点以及它的名字是什么。如果该项是一个控件,API 会让屏幕阅读器知道它是什么类型的控件。如果它是一个类似复选框的交互控件,API 会指示它处于什么状态——例如,选中或未选中。
听起来熟悉吗?这是应该的——这正是 WAI-ARIA 的目标,它让您能够向没有任何固有语义的小部件添加这些描述性的名称、角色和状态属性。这也是原生 HTML 控件所做的——它们公开它们的名称、角色等等(在这个阶段,你应该明白了!)传递给可访问性 API,当用户通过键盘给出一个项目焦点时,该信息被传递给 AT。
图 4-2 给出了正在发生的事情的概述,并展示了 DOM 的内容是如何可视化地输出到屏幕和屏幕阅读器的。
注意图 4-2 中的图表有点过于简化,但它的设计是为了概括核心 HTML 代码和屏幕阅读器输出的语音之间的交互。
***图 4-2。*可访问的 DOM 输出到屏幕和文本语音引擎
以下是上图中项目的描述:
- 第 1 项:HTML 元素—这些元素构成了 DOM。
- 第 2 项:DOM—这是辅助技术和浏览器用来构建文档图片的基础,以用户要求的方式呈现给用户。请注意,可视浏览器和非可视屏幕阅读器可以使用同一个核心 HTML 文档。这是相当惊人的,表明普遍接入是一个技术现实。
- 第 3 项:浏览器渲染引擎—这用于确定 HTML 和 CSS 的组合在浏览器中的视觉呈现方式。
- 第 4 项:浏览器—这是一个可视的屏幕显示,由浏览器的渲染引擎将 DOM 和 CSS 声明的内容组合在一起。它通常是视力正常的人上网时使用的主要焦点。然而,如果用户看不见,他仍然需要能够访问相同的内容。在更易访问的网页中,页面以分层的方式在浏览器中可视化呈现,例如,根据 CSS 定义的声明、由不引人注目且逐渐增强的 JavaScript 定义的行为,以及提供对辅助技术至关重要的语义的 HTML 或 WAI-ARIA 代码。
- 第 5 项:可访问对象树和可访问 API—可访问对象树从 DOM 映射而来。这是可访问性 API 被实例化的地方。
- 第 6 项:屏幕阅读器和离屏模式(OSM)—OSM 由屏幕阅读器维护。这两者之间存在着持续的相互作用。随着 DOM 内容的更新,OSM 的内容也需要更新。屏幕阅读器驱动文本到语音(TTS)引擎,该引擎是诸如 Nuance、ViaVoice、DECTalk 或 Microsoft Speech 之类的应用。
这是屏幕阅读器导航和语音输出的初始模型。但这是全部情况吗?用户交互之类的呢?
图 4-3 提供了一个包含交互模型的更完整的图片,并显示了交互和 TTS 输出。(为了使事情更清楚,我从图中删除了可视化浏览器。)
***图 4-3。*互动和 TTS 输出——一个动态的、互动的循环
以下是对图 4-3 中项目的描述:
- 第 1 项:用户通过键盘和语音输出导航或与页面交互—用户代理可能直接使用 DOM,也可能使用 OSM、可访问性 API 中实例化的可访问对象树和 DOM 数据的组合。因此,双向箭头描述了 DOM 中可以触发的事件,这些事件导致页面更新——特别是对于动态 web 内容。
- 第 2 项:可访问性 API 和 OSM—这些是通过 DOM 提供的,如前一项所述,屏幕阅读器可以直接与 DOM 交互,也可以与每隔几毫秒更新一次的可访问性 API/OSM 交互。
- 第 3 项:DOM—DOM 响应用户在浏览器中与 web 内容交互时触发的事件。
“无障碍”:电影,共同主演的“启发”
通常,屏幕阅读器需要额外的支持,以使最终用户更容易访问内容。为了做到这一点,屏幕阅读器使用了他们通过 DOM 获得的信息、可访问性 API(你刚刚见过的)和所谓的试探法的组合。这些评估帮助用户在几乎没有信息(例如无法访问的网页)的情况下构建更好的网页图片。
例如,如果一个网页的设计很糟糕,包含的可访问性信息很少(编码很差,等等),那么就没有什么信息可以传递给屏幕阅读器。接下来发生的是,软件使用一种方法,试图通过猜测(当然是有根据的猜测)在给定的上下文中找到的某些内容可能是什么或很可能是什么来找到尽可能多的信息。这叫做启发式评估。该软件激活一套规则,试图找出什么是什么。该过程可以包括通过查看图像周围的内容来确定图像可能是什么,或者通过查看顶行中包含的第一个项目(可能是标题)来猜测文档中的表格标题可能是什么。这种依靠试探法进行修复的方法很脆弱,容易出错——因此,语义正确的代码很重要。
注意术语“启发式”只是指“一套规则”
DOM 和动态内容的变化
离屏模型也可以认为是一个虚拟缓冲区。这个缓冲区是一个临时的内存存储,包含 DOM 在任何给定时间的快照。当这个页面没有变化时,这个快照是非常静态的,屏幕阅读器可以愉快地询问页面内容,用户不必太担心事情会发生变化。
注意我不是指好警察/坏警察方式的“审问”,而是指严格意义上的用户与网页内容的互动。你可以把这种互动想象成如下的对话:
问:你是什么?答:我是一个复选框。
问:你是检查还是不检查?
我检查过了。
这不像一个好警察/坏警察的例行公事那样激动人心或富有戏剧性,但是你要做什么?
当页面内容动态变化并且缓冲区需要更新时,这种情况就明显不同了(如前所述)。几年前,当 AJAX 作为一种开发方法出现,异步内容更新成为规范时,这是一个明显的问题,这要归功于XHR
对象。
注意 AJAX 开发人员将熟悉
XMLHttpRequest
或XHR
对象,它们可以通过减少对服务器的调用来促进更多的客户端功能,并有助于创建更加动态和响应更快的 web 应用。
虽然客户端更新很棒,是一个真正的进步,但 AJAX 或 Web 2.0 应用中的动态内容更新对更注重可访问性的开发人员提出了挑战。开发人员如何让 AT 知道部分页面内容已经更新?如何以一种不引人注目的方式做到这一点?在 WAI-ARIA 出现之前,这非常棘手,因为虚拟缓冲区的更新必须是强制的,用户才能看到 DOM 中的任何变化。现在这已经不是什么大问题了,因为虚拟缓冲区每隔几毫秒就会自动更新一次,所以 DOM 的变化可以更可靠、更快速地传递给用户。
注意对于一些关于这个问题的屏幕阅读器历史,如果你喜欢放松一点,我推荐以下 Gez Lemon 和 Steve Faulkner 在
[www.Juicystudio.com](http://www.Juicystudio.com)
发表的文章。Gez 和我也写了关于这个主题的文章,并在英国利兹的一次技术会议上提交了一篇论文,会议由大约五个人组成,我们是其中的两个人。所以这个主题确实有广泛的吸引力,哈哈!
欲了解更多信息,请访问 JuicyStudio 网站,查看[
juicystudio.com/article/making-ajax-work-with-screen-readers.php](http://juicystudio.com/article/making-ajax-work-with-screen-readers.php)
和[
juicystudio.com/article/improving-ajax-applications-for-jaws-users.php](http://juicystudio.com/article/improving-ajax-applications-for-jaws-users.php)
。
如果你正忙于一些脚本化的网页或应用,重要的是你要把它们开发成可访问的。这些事情是可能做到的,只是需要一些额外的关心和注意。
常用辅助功能 API
以下部分描述了一些最常用的可访问性 API。这些可以在不同的平台上找到,比如 Windows、Mac 和 Linux。有些也是跨平台的。
断续器
MSAA 是较老的老大哥 API,自 80 年代中后期以来一直在 Windows 平台上使用。有一个可访问对象,它是 MSAA 的核心,并且能够传递关于元素的角色、名称、状态和其他值的重要信息。
MSAA 通过向辅助技术对象发送有关程序元素的小块信息来传递信息。AT 帮助用户与应用交互所依赖的四个关键信息是元素的角色(控件做什么)、名称(它是什么)、值(它可以是数值或输入字段的值)和状态(是否选中复选框)。
注意 MSAA 的功能相当有限,不允许更复杂或高级的用户界面控制,它只能向 at 提供相对少量的属性信息。
欢迎来到自动售货机!
随着 Windows Vista 和更新的 Windows 版本的出现,MSAA 本应被 UIAutomation 部分取代。UIAutomation 是一个更复杂、更高级的 API,具有更丰富的对象模型。这个想法是,它将扩大 MSAA 的能力,但改善其缺点。
UIAutomation 将有关用户界面组件的信息以树的形式显示给辅助技术,类似于将 DOM 树暴露给允许 AT 使用 web 内容的可访问性 API 的方式。与组件相关联的任何属性也通过 API 显示给 AT,以及系统事件等等。
该 API 涵盖了一些常见的控件类型,如下拉菜单、组合框、复选框和其他将为 at 交互做准备的控件,以及显示其支持 AT 的功能和交互类型的控件模式。这些控件类型代表不同的功能,并且可以组合起来创建复杂的交互模型和控件。
注意在 MSAA 的介绍中,我说“部分替代”是因为它仍然被广泛用作平台可访问性 API,作为向 AT 公开信息的一种方式。然而,新的 API 在支持新的标记语言如 HTML5 和 WAI-ARIA 方面有很大的潜力。两种 API 都可以访问和共享 Web 和 OS 信息。
IAccessible 2
IAccessible COM 方法是 MSAA 的核心,它能够生成您反复遇到的非常重要的树结构。
记得你开始看到一种模式了吗?它完全是关于文档树,以及树上暴露给 AT 的各种叶子或节点,以及这些节点所具有的任何属性、状态等等。这是 API 可访问性的核心。
虽然 UIAutomation 代表了一个飞跃,它有潜力丰富地描述用户界面组件及其值和状态,但 IAccessible2 是一个替代 API,它扩展了 MSAA 的功能,而不是打算取代它。从版本 3 开始,它就被内置到了像 Mozilla Firefox 这样的浏览器中,并在 JAWS、NVDA、ZoomText(一个流行的屏幕放大程序)、Window-Eyes 等浏览器中实现。
Firefox 浏览器对 IAccessible2 的支持是一个非常有趣的发展,因为 Firefox 成为了许多测试更高级辅助功能的人的首选浏览器,比如刚推出的 WAI-ARIA。因为 IAccessible2 构建于 MSAA 之上,所以与现有的 API 没有冲突,开发人员可以利用对当前角色、状态和属性的支持,通过 API 向 AT 公开重要的可访问性信息。
注意【UIAutomation 和 IAccessible2 都具有跨平台 API 的能力。例如,IAccessible2 也用于 Chrome 浏览器。
苹果无障碍 API
苹果公司开发了可访问的 API,在 OSX 和 IOS 上都可以使用。这个可访问性框架是苹果在 Mac OS X 10.2 中引入的,旨在适应较旧的 Carbon 和较新的 Cocoa 开发者框架。这件事做得相当巧妙。它使用一个可访问性对象,以统一的方式向 Carbon 和 Cocoa 应用传递关于它自己的信息(同样,它的名称、状态、角色属性等等),而不考虑开发它所使用的框架。这些可访问性对象和传递用户界面组件信息的统一方式消除了软件开发的复杂性,并减少了代码分叉等需求。
操作系统附带的标准控件已经非常容易访问。只有当你设计你自己的自定义控件时,你才必须非常小心,并为对象提供名称、角色和(你猜对了)属性。
代码和界面生成器应用使向自定义控件添加辅助功能信息变得容易。
这实际上与应用/软件有关。网络呢?
Webkit 可访问性
Webkit 是支持 Safari 浏览器和许多其他浏览器的渲染引擎。Safari 支持优秀的屏幕阅读器 VoiceOver。从可访问性的角度来看,VoiceOver 完全改变了游戏规则。它拥有优秀、先进的导航和交互功能,一个盲人电脑用户现在可以在众多苹果设备上使用同一个屏幕阅读器。
Safari 背后的 Webkit 引擎为它提供了对许多 HTML5 元素和功能的大量支持(我将在下一章中介绍),如 HTML5 sectioning 元素、CSS3 web 字体、Web sockets、HTML5 表单验证、HTML5 音频和视频,以及隐藏字幕和臭名昭著的 2D JavaScript 渲染引擎 Canvas。(这个我以后再说。)
注苹果有开源的 Webkit,现在是 Chrome 浏览器背后的渲染引擎,还有 ion 和 Android 浏览器等。尽管 Webkit 已经外包,但这并不意味着 VoiceOver 在其他浏览器上的表现会特别好。并没有。它与 Safari 紧密相连,但 Safari 也是一个很棒的浏览器,所以这是一个双赢的局面。
LINUX 可访问性 API
您应该知道的主要 Linux 可访问性 API 是 AT-SPI,即辅助技术服务提供者接口。这是由 GNOME 项目开发的。UBUNTU 使用这个 API,UBUNTU 是 Linux 的一个优秀版本,为 ORCA 等屏幕阅读器提供了高级别的开箱即用的可访问性支持。
注意UBUNTU 操作系统还具有屏幕放大功能、修饰键(有点像 Windows 中的粘滞键)、语音识别支持和一个名为 Dasher 的有趣应用,它既不需要键盘也不需要鼠标,而是使用停顿功能和眼球跟踪器。它是完全免费的,所以非常值得一试。要查看更多内容并下载副本,请前往
[www.ubuntu.com](http://www.ubuntu.com)
。
HTML5 和可访问性 API
为了更好地了解 HTML5 如何映射到可访问性 API,我推荐由 Steve Faulkner(paci ello Group)和 Cynthia Shelly(微软)创建的文档。看起来可能有点抽象,但它可以让您很好地了解新 HTML5 元素的可访问性,因为它们需要映射到可访问性 API,以便 at 了解它们是什么、它们做什么以及如何与它们交互。
如文件所述:
所有特性和平台可访问性 API 之间没有一一对应的关系。当 HTML 角色、状态和属性不直接映射到可访问性 API,并且 API 中有一个方法来展示文本字符串时,通过该方法来展示未定义的角色、状态和属性。
IAccessible2 和 ATK 使用对象属性来暴露 API 中不直接支持的语义。对象属性是松散指定的名称-值对,对于在可访问性 API 中没有特定接口的地方公开内容非常灵活。例如,此时,HTML5 header 元素可以通过 object 属性公开,因为可访问性 API 没有这样的角色可用。
对于本身没有对象属性的可访问性 API,找到一个类似的机制或者开发一个新的接口来公开名称/值对是很有用的。在 Mac OS X 可访问性协议下,所有的 getters 已经是简单的名称-值对,并且在任何需要的时候都可以公开新的语义。请记住,这还需要与辅助技术开发人员合作,以获得对新语义的支持。”
注意概述 HTML5/API 映射的完整文本和详细表格可在
[
dev.w3.org/html5/html-api-map/overview.html](http://dev.w3.org/html5/html-api-map/overview.html)
获得。
所以这些都是正在进行的工作。当您阅读本文时,各种 API 到 HTML5 的映射肯定会有所改进。
我在这里包含了一个矩阵的截屏(图 4-4 ),它概述了 HTML5 元素如何映射到可访问性 API,这样你就可以了解它是什么样子了。更多信息可以在刚刚显示的 URL 中找到。
***图 4-4。*html 5 和 API 映射的屏幕截图
版权所有 2011 W3C(麻省理工学院,ERCIM,庆应大学)。保留所有权利。W3C 责任、商标和文档使用规则适用。
提示如果你想找出任何 HTML5 或 ARIA 控件有什么样的作用,你可以使用几个工具来做到这一点,如 INSPECT32 (Win)或 ACC probe(Windows 上的 MSAA/IAccessible2)。当您关注浏览器中的小部件时,这些工具将让您看到它们如何映射到可访问性 API。
结论
在本章中,您学习了可访问性 API、DOM、屏幕阅读器如何通过可访问性 API 从 DOM 接收信息,以及旧的但仍在使用的离屏模型。在未来的章节中,我们将更多地使用易访问性 API 而不是 OSM。如前所述,屏幕阅读器不是 AT 现有的唯一部分,但它是最复杂的部分之一。在接下来的章节中,当我们继续更详细地研究 HTML5 时,我们在这一章中所涉及的领域肯定会对你更好地理解 at 是如何处理代码有很大的帮助。此外,我希望你能更好地理解为什么你有时可能需要提供一些额外的东西来支持旧的,例如,不使用更高级的 API。
好消息是这都是可行的,只要稍加注意,您就能够构建易于访问的 HTML5 应用,这些应用可以被支持它的新浏览器轻松使用,同时对那些不支持它的浏览器也很友好。
五、HTML5:文档标记的新语义和新方法
在这一章中,你将开始更详细地了解 HTML5 规范,尤其是与可访问接口的开发最相关的方面。有许多新的 API 进行后台客户端/服务器处理和数据存储,可以用于丰富、响应迅速的应用,但您将看到的主要是 HTML5 影响用户可访问性的方面。
您还将看到新的 HTML5 元素和用于定义文档轮廓和新的结构形式的语义。
HTML5:有什么新消息?
HTML 的早期版本是相对简单的文档标记语言。它们允许文档被链接和引用,并为构建内容提供语义以支持小范围的浏览器和平台。这种多样的内容范围很广,从数据表到通过简单链接提供交互的内容(这实际上是 Web 的核心),再到表单控件,以及一些非常简单的媒体——实现了嵌入式图形。
但是真的是这样。这些项目构成了早期 HTML 标记语言能力的基础。聪明的人随后想出了压缩音频和视频的方法,比如使用 Flash、Silverlight、Maccies 的 QuickTime 或 PC heads 的 RealPlayer 等插件(以及这些插件的真正乐趣)。这些技术使得 Web 能够被用作像动画内容和视频这样的富媒体的平台。
注意视频现在是真正的大生意,在美国网飞占所有网络流量的 22-35%(取决于你问的是谁)。因此,交付平台的性质非常重要。是的,网飞是首批采用 HTML5 向客户提供视频服务的公司之一。
HTML 的这些早期迭代被认为远远超出了职责的要求,因为 Web 已经远远超越了仅仅作为文档的页面,进入了应用空间等等。
好了,那么 HTML5 有什么新功能?相当多。以至于 HTML5 完全打破了仅仅是声明性文档标记语言的模式。HTML5 有许多新特性,涵盖了大量令人兴奋的新功能。在许多方面,它的大部分可能看起来不太像 HTML,事实上,这种语言远远超越了它的前辈。HTML5 确实是一项颠覆性的技术。
警告对于任何新的或改变游戏规则的技术,你都必须小心谨慎,采用灵活的试错法。HTML5 的采用方式(至少在某种程度上)是该规范制定了解析规则,为浏览器制造商提供了一个构建浏览器的标准。浏览器内的支持通常是以零碎的方式提供的。随着规范的发展,浏览器供应商可能只实现其中的某些部分。
从可访问性的角度来看,最终结果是浏览器或辅助技术(at)供应商支持或不支持的内容似乎有点武断。例如,CSS2 在浏览器中得到广泛支持绝对需要几年时间。当它最终被支持时,它通常只得到部分支持,这导致了错误和故障(例如“盒子模型渲染不一致”)。在 AT 的世界里也有同样的特性。例如,< table>
元素的<scope>
属性使得在 HTML4 中创作更易访问的数据表比使用更受支持的<headers>
和for/id
方法要快得多。然而,对它的支持是如此之少,不幸的是,这种更简单的创作方法不能被依赖。
新的 HTML5 语义
HTML 是一种很大程度上与意义相关联的语言。有些您已经熟悉的控件具有固有的行为(如通过键盘可点击或激活的链接等),但这些行为是由用户代理(如浏览器)处理的。底层代码提供了一个基本结构,允许核心内容(通常是文本)被广泛的设备消费。这一内容层为“一次创作,发布到多种设备”的模式提供了实用的基础,该模式为电子通信提供了巨大的优势,实现了互操作性,而无需在过多的设备之间进行大量定制。
注意html 5 规范对元素的使用非常严格。
当您想到语义对互操作性和可访问性的重要性时,前面的观察确实有意义。想想我们已经讨论过的关于结构化内容在支持可访问性架构和通过可访问性 API 向 at 传递可用信息方面的重要性。如果你的头还疼的话,我很抱歉,但这一切现在应该清楚一点了。
然而,HTML5 规范中非常明确的“正确的工具用于正确的工作”的规则在野外确实失效了。开发人员几乎只是做他们想做的事情,只要它对他们的目的“起作用”。同样值得注意的是,当涉及到可访问性时,“它看起来不错,很有效,只是不要在引擎盖下看得太近”的概念真的不成立。
这是因为只有当你做一些专家的可访问性审计或真人用户测试时,隐藏在引擎盖下的东西才可能暴露出来。我们将在第九章中更详细地讨论这个话题。
可以说,新规范给出的建议关注的是软件的互操作性,而不是它对最终用户的影响。事实上,该规范试图不定义用户体验,并且在某种程度上存在双重标准。为什么?因为规范的某些方面确实详细地描述了用户体验应该是什么样的。然而,当谈到可访问性时——通常情况下——这并没有明确的描述。
语义忍者
同样值得注意的是,虽然我对一些开发人员对他们代码的态度有点厌烦(“对我来说似乎没问题,所以没问题”),但如果开发人员拼凑的东西对残疾人有效的话,这实际上对我来说是没问题的。我想我对不适合残疾人和老年人的网络内容有特别的偏见。我之所以提到这一点,是因为对于可能使用 ATs 的残疾人来说,格式良好的代码、严格的验证,甚至语义正确性在积极的用户体验中排在第二、第三和第四位。
理想情况下,这些应该支持可访问性,并且在很多方面都支持——但不是在所有时间和所有情况下。如果良好的格式、验证和语义正确性是可访问性的铁一般的保证,那对所有人来说都是快乐的日子,但事实并非如此。所以不要绝对地思考;当涉及到 HTML5 和可访问性时,有许多相对的考虑。
所以当你读到这里的时候就很清楚了:我完全支持遵守规则,但前提是它们的工作方式不会破坏残疾人的用户体验——或者实际上没有残疾。我不太关心良好编码的规则,良好的格式,或者符合规范的规范大纲,或者你想叫它什么。话虽如此,我并不纵容草率的代码或以任何陈旧的方式设计代码;我只是承认,有时候你必须遵循自己的直觉或有洞察力的经验判断,而不仅仅是规范所规定的。
有些人自称了解可访问性,但实际上他们是规范狂热者,可能是验证吸血鬼。符合任何一种方法都不能保证可访问性、良好的可用性或积极的用户体验。所有这些开发工具真正能做的是表明开发人员在编写符合正式发布的语法的代码时知道她在做什么,但它们不一定在用户代理支持方面考虑用户体验,也不一定在浏览器或 at 上工作。唯一有助于开发人员理解实际情况的是用户测试或熟练使用屏幕阅读器的体验。在这一点上,开发人员自己的测试可能有助于发现什么时候工作或者不工作。这种知识非常重要,因为它基于用户体验的主观现实。
注意好吧,其实格式良好的代码很重要。良好的语义非常重要,但是现实世界的可访问性非常微妙——特别是对于新的内容和元素类型。然而,请记住,一个未编码的&符号(它将抛出一个验证错误)永远不会导致一个不可访问的网页。在网络文档上有一些标题结构,而不是没有,比仅仅确保标题以正确的方式排序要重要得多。
语义禁忌
处理新元素的 HTML5 规范的介绍部分警告不要使用不一致的内容和以不一致的方式使用一致的元素。建议您不要使用不一致的属性值(例子中为"carpet"
)和不一致的属性(例子中为"texture"
),这在 HTML5 中是不允许的。这些工具的用法如下所示:
<label>Carpet: <input type="carpet" name="c" texture="deep pile" /></label>
知道这一点当然很好——不是很有用,但是很好。然而,规范建议下面的代码示例更符合语义,因此可能是有效的 HTML5:
<label>Carpet: <input type="text" class="carpet" name="c" data-texture="deep pile" /></label>
注意我不是在拿地毯的例子开玩笑!可以在
[
dev.w3.org/html5/spec/Overview.html#elements](http://dev.w3.org/html5/spec/Overview.html#elements)
上查看。
好吧,虽然这个例子一开始看起来有点傻,但它不是没有目的的。你可以从中看出语义变得更有意义了。<input type="text" />
段是被赋予任意属性的标准输入(class="carpet"
)。data-texture="deep pile"
段会被不了解它的用户代理忽略,这是他们全部!
更严重的是,如果你有一个文档片段可以用来表示一个公司网站的标题,这也是不符合要求的,因为第二行不是一个小节的标题,而仅仅是一个副标题。你可能认为语义有点不确定,你是对的。然而,在早期版本的 HTML 中没有办法定义分组标题之间的关系。您可以看到以下不符合项:
<body> <h1>ABC Company</h1> <h2>Leading the way in widget design since 1432</h2> […]
HTML5 引入了一个<hgroup>
元素来帮助定义一个标题在哪里可以有一个直接子标题,比如你在这里看到的:
<body> <hgroup> <h1>ABC Company</h1> <h2>Leading the way in widget design since 1432</h2> </hgroup> […]
当你有一个为你的网站或项目提供一个很酷的标语时,这种代码是很有用的。例如,如果您有一个动物收容所的网站,您可以使用以下代码:
<hgroup> <h1>Animal Sanctuary</h1> <h2>A lifeline for all creatures great and small</h2> </hgroup> ...
图 5-1 显示了一个页面中的清单 5-1 中的代码示例,以及加入一点层叠样式表(CSS)样式后的样子。
***清单 5-1。*使用<h 组>
`body
{
background-image:url(…/img/gray_white_tile2.png);
}
#hg
{
margin: 10px;
padding: 10px;
border-radius: 15px;
background-color: #333;
height: 80px;
margin: 20px;
padding: 15px;
}
h1
{
font-family: Lucida Sans Unicode, Lucida Grande, sans-serif;
color: #C90;
background-color: #333;
margin: 0;
padding: 0;
border-radius: 15px;
}
h2
{
font-family: Century Gothic, sans-serif;
color: #FFF;
font-size: 50%;
}`
***图 5-1。*利用新<组>举例
注前面的例子是一种新的文档布局方法的开始。这是一种更复杂的定义内容和轮廓的方式,在 HTML5 中使用了新的元素,比如
<section>, <article>, <header>, <footer>,
等等。HTML5 规范警告说,使用脚本会改变许多属性、文本的值,甚至整个文档的结构。您可以很容易地动态实现这一点,这样用户代理就必须更新文档的这些语义,以便正确地表示文档的当前状态。维护文档的语义完整性非常重要,这样互操作性和可访问性也可以得到适当的支持。该规范确实建议作者“尽可能使用声明性替代脚本,因为声明性机制通常更易于维护,并且许多用户禁用脚本。”这是个好建议。
html 5 中的全局属性
以下是可以添加到任何本机元素的常见属性:
accesskey
class
contenteditable
contextmenu
dir
draggable
dropzone
hidden
id
lang
spellcheck
style
tabindex
title
您以前见过一些这样的全局属性,例如id
(一个元素的唯一标识符,可以用作 CSS 或 JavaScript 的钩子)class
(与id
相同,只是它可以在许多元素上重用)title
(元素的咨询信息)accesskey
(一种提供作者定义的快捷键的方式)tabindex
(为元素提供连续的键盘焦点)style
(添加 CSS),等等。
注意有了
accesskey
属性,作者就可以在他们的网页内容中添加快捷的快捷键。这似乎是一个好主意,除非你使用 AT——因为如果你这样做,这些击键已经做了一些事情!作为一名作者,我强烈建议您避免使用访问键,除非您可以找到一些保留键,这些键还没有被大部分 at 使用。顺便说一句,祝你好运。
有许多事件处理程序属性也可以添加到任何 HTML 元素中:
- 奥纳博特
- onblur*
- 在线播放
- 在线播放
- 昂哥
- 单击事件
- 上下文菜单
- oncuechange
- ondblclick(点击鼠标)
- 忍无可忍
- 不可忍受
- 翁德拉贡特
- 软骨叶
- 昂格洛夫
- ondragstart
- 羔羊
- 老化变化
- 一个提示
- 统一的
- 恐怖片*
- onfocus*
- 推理能力
- on 无效
- 叔叔家
- 有印刷机吗
- onkeyup
- 加载*
- onloadeddata
- onloadedmetadata
- onloadstart
- 鼠标点下时
- 鼠标移动
- 你真大胆
- 鼠标悬停
- 是 mouseup
- 鼠标滚轮
- ONP 原因
- 蒙皮
- 播放中
- onprogress
- 最新变化
- 无期
- onscroll*
- 被发现
- 观察
- onselect
- 昂什
- 安装
- 昂松宾
- 暂停
- 按时更新
- on volume exchange
- 等待中
注意前面标有星号的事件处理程序可能会改变含义,这取决于它们使用的上下文——在本例中,如果它们用在
<body>
元素或窗口对象上。
再来点咏叹调吗,先生?
该规范还建议,对于可能需要比当前 HTML5 规范所能提供的更多细节的辅助技术产品,可以为辅助技术产品指定一组注释(ARIA 角色和 aria-*属性)。
我们在前面的章节中已经介绍了 ARIA 的很多内容,但是这里有必要概述一下 ARIA 和 HTML5 是如何一起工作的,因为它们都有本地语义。
这里有一个启发性的引用,直接取自 HTML5 规范:
"下表定义了适用于 HTML 元素的强本机语义和相应的默认隐式 ARIA 语义。第一列中的每个 HTML 语言特性(元素或属性)暗示了同一行第二列的单元格中给出的 ARIA 语义(角色、状态和/或属性)。当多个行应用于一个元素时,必须应用定义角色的最后一行中的角色,并且必须组合所有行中的状态和属性。以下是这一工作方式的详细列表。”1
表 5-1 概述了强本地语义及其相应的默认隐式 ARIA 语义。
1
注意在 ARIA 被添加到原生 HTML5 元素的情况下,一般来说,添加的 ARIA 语义将胜过 HTML 并覆盖默认语义。然而,在某些情况下,这不会发生,并且有一些限制适用。还要注意的是,任何元素都可以被赋予表现角色,不管表 5-2 中显示的限制。
版权所有 2011 W3C (MIT、ERCIM、Keio),
其中一些看起来相当复杂和粗糙,乍一看确实如此。然而,最好了解 HTML5 和 WAI-ARIA 等新增语言之间的语义相互作用。正如您之前看到的,这两者有许多相似之处。
内容模型
新的 HTML5 元素的定义方式包括以下信息:
- 元素所属的类别
- 可以在其中使用元素的上下文
- 内容模型概述了应该包含的元素的子元素
- 元素应该实现的 DOM 接口
注意属性可以有任何字符串值,包括空字符串。有一些限制,但这些一般规则适用。
内容模型概述了元素应该包含的内容。仔细想想,这是有意义的,因为它有助于清晰地勾勒出内容应该如何表现,以及浏览器在遇到某些项目时应该做什么。当您考虑嵌套项应该如何表现时,这也变得更加相关。通常,元素的使用必须遵循其内容模型。
注意当处理强语义和弱语义,或者在某些上下文中“什么胜过什么”的决定时,这可能会有点模糊,比如你可以在表 5-1 和表 5-2 中看到的那些。我提到了对元素进行分组的 HTML 内容的类别,下面是它们的列表:
元数据内容
流动内容
切片内容
标题内容
语法内容
嵌入内容
互动内容
规范中有一个很好的交互式 SVG 图,直观地展示了这些类别之间的关系。更多信息,请访问[
dev.w3.org/html5/spec/Overview.html#kinds-of-content](http://dev.w3.org/html5/spec/Overview.html#kinds-of-content)
。
元数据内容
元数据内容是概述页面内容的行为或表示的内容。您将习惯使用的是典型的元数据内容,如 JavaScript 和/或 CSS,使用以下元素:
-
<命令>
六、HTML5 中的图像、富媒体、音频和视频
在这一章中,你将看到如何使用 HTML5 来制作图像和其他富媒体。这一章将介绍一些使图形内容可访问的可靠方法,以及一些你可能不熟悉的新技术。我将介绍用于处理富媒体的其他元素,比如
<audio>
和<video>
,并讨论如何使用这些新元素以一种易于理解的方式呈现音频和视频内容。就 HTML5 的“新”特性而言,没有什么比新的
<canvas>
元素更引人注目了。<canvas>
是一个 2D 绘图 API,可用于在浏览器中创建一些非常复杂、图形丰富的动画。然而,<canvas>
内容确实有一些特殊的可访问性挑战。我稍后会讨论这些。注而
<canvas>
的优势在于将图形丰富的内容原生带入浏览器,无需第三方插件。Flash 内容不会消失,因为从可访问性的角度来看,它仍然有比<canvas>.
更合适的用途使图像可访问
网络主要是一种视觉媒介。虽然这是真的,但您已经看到,Web 也是一种令人惊讶的多样化媒体,许多用户,无论能力如何,都可以访问相同的内容并在网上有相似的体验。它在范围上是通用的,因为它支持多种访问模式,而不管能力如何。
太棒了。然而,有时你需要注意一些用户经历的限制,并通过正确应用标记和良好设计的原则尽你所能。
当试图使内容具有可访问性时,使图像具有可访问性通常是 web 开发人员首先要学习的事情之一。学习如何做是非常容易的,所以作为一种介绍性的可访问性技术,它的入门门槛相当低。然而,通常很容易做错或者误解你最初想要达到的目标。
来认识一下无障碍网页设计的典型代表:alt 属性
<image>
元素的alt
属性(或@alt
)是您最常用来提供图形内容的文本替代物。这采用以下一般形式:<img src="someimage.png" alt="Some text that provides an equivalent description or functional replacement for the image" />
所以就整体结构而言,它相当简单。您有
<img>
元素,后面是它的source
属性和@alt
。属性的顺序并不重要——如果您愿意,可以先有@alt
,再有src
。使用前面的方法将@alt
明确地与图像相关联,并且它表示完整的结构。在所示的方法中添加替换文本也绝对不会影响图像的视觉呈现。注意
<img>
元素还有一个title
(@title
)属性;然而,使用@alt
属性通常是提供替代文本的更健壮、更可靠的方式。对于更长的描述,还有@longdesc
属性。这些我以后再说。屏幕阅读器如何处理@alt 文本
当屏幕阅读器将焦点放在网页中的
<img>
元素上时,屏幕阅读器首先向用户宣布它遇到了一幅图像。它通常通过说出“图像”这个词来做到这一点如果图像有一个@alt
值,它将宣布作者在其中包含的任何文本字符串。就这样。注意
@alt
在大多数图形和文本浏览器以及最常用的屏幕阅读技术中都得到了很好的支持。如果没有一个
@alt
描述,屏幕阅读器将查看是否有一个title
属性,并可能(我说可能是有原因的)宣布它。如果两者都不存在,屏幕阅读器将试图寻找它能找到的任何其他支持信息,通常是通过宣布src
属性的内容,这可能给用户一些图像类型或图像目的的指示。注意当图像不可用或无法加载时,大多数浏览器会在图像应该出现的地方显示一个边框,同时还会显示替换文本。默认情况下,Lynx 等纯文本浏览器会读取替代文本。详见
[
en.wikipedia.org/wiki/Lynx_(web_browser)](http://en.wikipedia.org/wiki/Lynx_(web_browser))
。例如,假设一个图像是一个按钮,没有替代文本或
@title
信息。如果文件被命名为 button.png 或其他描述其功能的名字,如 logon.png 或 logout.png 的*,这可以帮助屏幕阅读器用户了解按钮的实际用途,即使缺少文本@alt
。*注意一般情况下,我描述的情况在没有
@alt
或者@title
的地方会触发所谓的启发式评估。一个启发式是经验法则或评估方法。试探法是各种事物的核心,从学习计算机科学时可能学到的基本逻辑,到更高级的算法设计。不要被这个术语所困扰,只要想想“一套规则”有时,当启发式评估被触发时,屏幕阅读器也会查看网页中周围的 HTML 内容。另一方面,如果你的图片有一个我称之为可怕的 URL,这是一个内容管理系统(CMS)可能会使用的随机字符串( 12090_IMG.jpg 或类似不透明的东西),屏幕阅读器将无法理解它。这将给最终用户带来问题,因为当丢失的
@alt
触发屏幕阅读器试探法时,软件将无法理解内容。它将输出文件的名称,但是如果这是一个长的,随机的文本字符串,它是没有用的。记住一个好的默认行为是给你的图片起一个描述性的名字,即使你实际上是在应用替代文本描述。
@alt 缺点
因此,看起来似乎
@alt
属性非常健壮、可靠,而且都是好东西。有什么弊端吗?有一种观点认为,替代文本可能对“每个人”都有用,除了那些使用纯文本浏览器或有视觉障碍并使用屏幕阅读器的用户之外,其他用户也应该可以使用替代文本。虽然这听起来很有道理,也很包容,但我并不是很认同这个观点。当然,在某些情况下,替代文本描述有助于理解,但总的来说,我觉得就它所做的和它所服务的群体而言,它做得很好。这是一个漫长而微妙的讨论,我不需要在这里赘述。可以说,在 HTML5 工作组中,争论的焦点是“你不允许有视力的人访问@alt
值,这是对他们的歧视。”对我来说,这种想法充其量是虚假的。一种能很好地满足 80%用户需求的标记语言要比一种不能很好地满足 100%用户需求的标记语言要好。另一个潜在的问题是对文本大小的限制。从技术上来说,它大约是 100 个字符,但一般来说,很难得到一个关于“太长”到底有多长的明确答案。如果你从一开始就知道你的图像需要更长的描述,有其他方法(如
@longest
和 WAI-ARIAaria-labeledby
)可以替代。我应该怎么描述?
当开发人员试图为图像提供可选的文本描述时,面临的最大挑战之一就是到底要描述什么。这是一个很大的问题,不幸的是,这个问题通常没有实际意义。事实上,这个区域有点模糊。这可能不太让人放心,但你在这里。一些屏幕阅读器用户确实希望尽可能详细地描述每一件事情,而另一些用户只要能在任何给定的时间获得他们需要的信息就很高兴。更重要的是,当一个网站有一个特定的功能时,许多用户仅仅是为了能够完成他们设定的任务而感到高兴。他们不在乎图形是否被描述,只要他们没有丢失任何核心功能。
我在这里要做的是概述一些我多年来从做网站的用户测试和专家评估中学到的东西。这通常涉及与盲人屏幕阅读器用户以及其他辅助技术(AT)设备的用户一起工作。我将介绍当前关于 HTML5、图像和其他富媒体的可访问性最佳实践的想法。那我就让你自己拿主意了!
描述内容:不要过度
我想传授给你的第一条智慧是“不要做得太过”有时候少真的就是多,而大多数时候,适可而止其实就是适可而止。最初,你可能觉得有必要描述,嗯,一切!这通常是非常不切实际和耗时的。学习保持你的文字描述的相关性和简洁是一门艺术,你需要花一些时间来掌握。有了经验,你会发现什么样的细节是不重要的,最好不要用文字描述图像。
忽略它(第一部分)
如果你真的站在一个用户的立场上,你可能会发现有些情况下你真的不希望一张(或多张)图片被解释。事实上,为了获得最佳的用户体验,您可能希望图像完全隐藏或被忽略。所以在我继续讲下去之前,我应该回答一下我想我听到你问的问题:“我如何把一张图片留在外面?我如何不将它包含在屏幕阅读器输出的内容中?”你可以用几种不同的方法做到这一点,而且它们很容易掌握。
当网页加载时,文档中的所有 HTML 项目都被加载到 DOM 中。显然,这包括所有的图形和其他富媒体。如果你想让一个图形在视觉上呈现出来,但是你想让屏幕阅读器忽略它,最常用的方法之一就是给图像一个空值
@alt
。这采取以下形式:<img src="someimage.png" alt="" />
注意
@alt
的引号之间没有空格。这对屏幕阅读器来说是一个标志,告诉它忽略这个图像。屏幕阅读器会表现得好像图像根本不存在一样,不会通知用户它的存在。
“我为什么要这么做?”你可能想知道。好吧,如果一个图像纯粹是表示性的,比如你用来设计一个按钮的内嵌图形,你会想把它从屏幕阅读器中隐藏起来,因为它对用户的体验没有任何帮助。当你仔细想想,有很多图像你真的根本不需要描述,因为它们没有增加任何价值。所以 null
@alt
是一个强大的朋友。明智地使用它,你会发现它真的有助于去除页面中不必要的混乱。忽略它(第二部分)
隐藏对屏幕阅读器用户没有信息价值的图像的另一种方法是使用级联样式表(CSS)。这一声明采取以下形式:
p {background-image:url('some_bullet.png');}
在这个例子中,您可以将元素名
p
替换为您想要应用图像的任何元素。URL
部分指向您存储想要使用的图像的位置。默认情况下,该属性也是重复的,所以您可能想要设置一个no-repeat
,如下所示:p {background-image:url('some_bullet.png'); background-repeat: no-repeat; }
如果您希望图像在 X 访问上垂直重复,您的代码将采用以下形式:
`body
{background-image:url(‘some_repeatinggraphic.png’);
background-image: repeat-x;
}`要在 Y 轴上水平重复图像,请使用:
Body {background-image:url('some_repeatinggraphic.png'); background-image: repeat-y; }
您可能会发现您想要使用一些内联 CSS 来呈现您的图像,因此您可能会使用一些
<div>
或内联<span>
元素来充当图像的挂钩。忽略它(第三部分)
另一种对屏幕阅读器隐藏图像的方法是使用 WAI-ARIA 角色,
role="presentation"
。它采用如下所示的形式:<img src="some_prettybutsemanticallyuselessgraphic.jpg" role="presentation" />
然而,我真的不建议这样做——部分是因为前两种方法更好地被当前和旧的用户代理支持,部分是因为使用
role="presentation"
在支持它的用户代理中有其他与可访问性相关的用途(大多数最新的屏幕阅读器和浏览器都是这样)。例如,如果您希望屏幕阅读器忽略父元素的语义,但不忽略子元素,这种技术就非常有用。例如,您可能需要使用一个表格来包含小部件和控件布局。使用role=“presentation”
允许屏幕阅读器忽略用于包含小部件控件的表,但是它允许屏幕阅读器访问子语义(小部件的内容)。一个巧妙的诡计。此外,请不要向我开枪,或者让长翅膀的猴子攻击我的家——用桌子来布置不是什么可及性禁忌。
不同种类的图像
我刚刚概述了一些对屏幕阅读器隐藏内容的有用技术。
那么如何写出好的替代文字呢?你从哪里开始?首先,有几种不同的图像需要考虑:
- **视觉上丰富的图像:**一般来说,照片、素描、绘画都是视觉内容非常丰富的。例如,考虑一幅美丽的自然风景或一张全家福。很难真正捕捉到这些类型的图像或它们的精神。
- **图形和图表:**这些图形和图表种类繁多,但可以包含非常详细的信息,以及说明各种数据之间的关系。
- 文本图像:这可以是包含用户不会错过的重要有用信息的图像,或者只是包含样式化的文本的图像。
- **功能图像:**这是具有特定功能的图像,例如用于按钮的图形。
- 装饰性图像:没有实际功能的图像,只是作为纯粹的视觉点缀有用,比如一个漂亮的项目列表。
- **图标:**用作视觉线索的图像,是链接的一部分。
正如您所看到的,替代描述的用例有许多种,这个列表甚至还没有穷尽!在我们继续之前,我们先来看看 HTML5 中的一些新元素,它们可以与
@alt
和其他描述图像的方法结合使用。html 5 在描述图像方面有什么新功能?
描述或注释大量图表、照片和插图的两个新手是
<figure>
和<figcaption>
。它们被用来创建一个单个单元,可以从网页的另一部分指向或引用。这就像在你的 CSS 中指向一个 ID。图形充当某些图像、图表、插图或照片的容器,它采用以下基本形式:
`
好的,这就是不穿衣服的样子。要把它打扮的漂漂亮亮的,适合出门,还得加个
<figcaption>
来完成结构。这基本上是图的标题。将
<figcaption>
添加到<figure>
的基本结构如下所示:`
Some useful description of the image `因此,
<figcaption>
仅仅是:<figure>
内容的标题。接下来是更详细的例子。我只想概述一下基本结构,并说明在 HTML5 中使用
<figure>
比使用@alt
有一个有趣的优势,因为它代表了一个完整的结构化单元,可以在页面上引用。用咏叹调描述一个形象——描述者
使用
aria-describedby
属性是引用页面中元素的另一种方法,它提供了图像的适当描述。这可能是一个非常有用的方法,因为页面中的现有文本经常可以完美地描述一幅图像。与其复制这些文本,不如以编程方式引用图像的 ID。这样你就在图像和文字描述之间建立了一个明确的联系。
例如,考虑下面的图像。第一张(图 6-1 )是我和我的岳父菲亚克拉在爱尔兰最高的山峰上的照片,该山峰位于克里郡的 Carrauntoohil。这张照片拍摄于 2011 年夏天。
***图 6-1。*乔希(右)和他的岳父菲亚克拉(左),在凯里郡的卡劳恩图希尔山顶
如果这张照片被嵌入到一个谈论我们攀登的 HTML5 博客中,在添加图片和描述之前,博客帖子的代码看起来会类似于清单 6-1 中所示。
***清单 6-1。*一篇 HTML5 博文
`
my big climb this summer (2011) Climbing the three highest mountains in Ireland
During the summer of 2011, Fiachra, Dara and I climbed the three highest mountains in Ireland. This was a stupendous day where the challenge of summiting the three peaks of Carrauntoohil, Beenkeragh & Caher was too much to resist!
The Coomloughra Horseshoe
The three peaks are ringed within in a large horseshoe shaped valley and present a very challenging climb even for experienced hill walkers. We also had fantastic views of the MacGillycuddy Reeks from Beenkeragh's high, exposed summit. The weather was also very beautiful and we totally lucked out as we couldn't have asked for a clearer day to see the spectacular views. We walked over Beenkeragh Ridge with its yawning drops and navigated the equally spectacular Caher Ridge, with the Black Valley far below, before descending from Caher into Coomloughra Glen.
Remember to bring water
It was a very hot day and after 4 hours or so we ran out of water! Fortunately we came across some fresh mountain streams in the Coomloughra Glen and could top up our water bottles […]
如果我想在第一段中包含图片,并且我想把这一段作为文本描述,我可以像清单 6-2 中所示的那样编码。
***清单 6-2。*在帖子中包含一张图片
`
My big climb this summer (2011) Climbing the three highest mountains in Ireland
**
**During the summer of 2011, Fiachra, Dara and I climbed the three highest mountains in Ireland. This was a stupendous day where the challenge of summiting the three peaks of Carrauntoohil, Beenkeragh & Caher was too much to resist!
The Coomloughra Horseshoe
The three peaks are ringed within in a large horseshoe shaped valley and present a very challenging climb even for experienced hill walkers. We had fantastic views of the MacGillycuddy Reeks from Beenkeragh's high, exposed summit. The weather was also very beautiful and we totally lucked out as we couldn't have asked for a clearer day to see the spectacular views. We walked over Beenkeragh Ridge with its yawning drops and navigated the equally spectacular Caher Ridge, with the Black Valley far below, before descending from Caher into Coomloughra Glen.
Remember to bring water
It was a very hot day and after 4 hours or so we ran out of water! Fortunately we came across some fresh mountain streams in the Coomloughra Glen and could top up our water bottles […]
那么刚才显示的代码中发生了什么呢?我使用博客文章的内联文本来描述图像,通过它们的 id 指向 block 的内容。在本例中,我分别给了每个
<p>
元素一个 IDtext1
、text2
和text3
。对于支持aria-describedby
的用户代理(如前一章所述,许多新的屏幕阅读器都支持,那些不支持的只会忽略它),在图像和描述之间创建一个编程连接意味着一旦图像获得焦点,描述就会被公布。此外,有一些方法可以增强这种基本行为——例如,通过向图像添加一个@alt
文本描述,并将其与aria-describedby
代码相结合。这看起来有点像清单 6-3 中的代码。(我省略了博文代码的第一部分和最后一部分。)***清单 6-3。*增强图像描述
`
Climbing the three highest mountains in Ireland
**
这种方法的有趣之处在于,它为不支持
aria-describedby
但能理解@alt
内容的旧屏幕阅读器引入了向后兼容的元素。像这样处理您的标记通常是一个好主意,因为它涵盖了支持和不支持新特性的用户代理。支持这两者的屏幕阅读器实际上将通过
@alt
和aria-describedby
元素的内容获得丰富的文本对等物;然而,要知道aria-describedby
技术目前只能用于页内描述。因此您不能引用不同网页上的描述。注意当一个屏幕阅读器用户厌倦了描述或者听够了描述,他可以离开被描述的条目,转到下一个,或者他可以使用他的屏幕阅读器的导航功能。所以用户不必听他不想听的东西——一旦用户移动到一个新的 HTML 元素,屏幕阅读器的输出就会结束。
我应该使用哪种方法?
一般来说,这个决定归结于使用的上下文和什么是最好的描述。机制可能会有所不同,因为您正在寻找各种方式来提供描述,但在您开始之前,有一些因素您需要仔细考虑。为了进一步说明您之前看到的示例或图像类型,我们将讨论以下情况(按照之前列出的项目顺序):
- **视觉丰富的图像:**当照片、图画或绘画等图像具有大量视觉信息时,
@alt
或<figcaption>
可以用作标签,简要描述图像或给出图像的概述。 - **图形和图表:**当图像是富含信息数据的图形或图表时,
@alt
可以用作描述性标签,给出图形主旨的简要概述。图形和图表是其他方法如aria-describedby
非常有用的完美场合。 - **文本图像:**图形设计师可能使用了用户机器上没有的 groovy 字体(在网页设计中很常见,被称为图像替换技术),而
@alt
被用作图像的替换。@alt
应该清楚地说明样式文本是什么。 - **功能图像:**图像可能有功能,所以你用
@alt
来描述它做什么,而不是它看起来像什么。 - 一个装饰性的图像:一个图像可能完全是装饰性的,不需要替代的描述,它需要被隐藏起来。
- **图标:**一幅图像可能被用作视觉线索或图标,并且是链接的一部分。
以下是支持上述用例的一些示例。
第一类:描述视觉上丰富的图像
图像通常包含大量视觉丰富的信息。很难用临床或精确的方式来描述它们。虽然你知道古老的格言“一张图胜过千言万语”,但反过来也是正确的吗?需要一千个字来描述画面吗?这可能有一定的道理。
尽管 WCAG 2.0 建议你为图片提供的文本应该是等价的或者应该替换图片,但实际上这通常是不可能的。至少不是在描述能真正做到画面公正的意义上。想象一下,试图为一幅像“蒙娜丽莎”这样的画提供文本描述。
你可以说,“这是一位带着淡淡微笑的优雅女士,”但你也可以说,“这是一位微微皱眉的优雅女士。”取决于你问的是谁,这两个问题都是正确的,而且都是描述性的。
所以,即使一幅图像非常丰富,你最好不要试图捕捉每一个细节,而是通过有趣的方式使用
@alt
或<figcaption>
来捕捉图像的精神。例如,考虑一下图 6-2 中显示的照片,我认为这很有趣,因为拍摄对象可能是兄弟,除了其中一个是紫色的。***图 6-2。*我的小男孩和他的猫头鹰伙伴
这是我儿子 Ruairí和他的大(亮紫色)猫头鹰朋友 Minerva 的照片。如果我将
<figure>
和<figcaption>
与@alt
结合使用,下面的描述可能更适合我要说的内容:`
<img src="Ruairi.jpg alt=“Ruairi smiling and playing on the couch at home with his large purple Owl friend Minerva. There is a likeness in their big Moon heads!” />Two friends together, Ruairi and Minerva `我在这里所做的是使用
@alt
作为一种提供更长描述的方式,而<figcaption>
仅仅是图像的标题。它们可以用于相互支持,并提供图像的各种类型的信息描述。我想说的是,有时很难写出一幅图像的有用的文字描述。如前所述,链接到图像的单独描述或使用
aria-describedby
指向文档本身的描述可能会更好。好吧,所以前面的照片很简单(虽然很可爱!).让我们考虑一些更复杂的图像,以及如何使用 HTML5 提供文本描述。
想想下面几张我过去作为艺术家的照片。(我指的是“我曾经这样做过”意义上的前世,而不是“前世”意义上的——但我想这是另一天的讨论了!)
图 6-3 是我多年前画的一张黑白钢笔画,名为《创造》。
图 6-3。《创世纪》
如果我把它放在一个在线图库中,并想用另一种文字描述来描述它,我能有效地做到吗?从技术上来说,我可以给它一个文字描述,但我如何传达其完整的视觉冲击或意义?
我可以试着做一些相对简单的事情,比如:
`
Pen and Ink Drawing called ‘Creation’ by Joshue O Connor `我的内容几乎达到了之前提到的 100 个字符的限制,而且——让我们面对它——描述并没有真正做到这一点。
我可以决定采用更详细的方法,使用
aria-describedby
方法,如下所示:<figure><img src="josh_drawing_creation.png" alt="A large colourful pen and ink drawing with a cosmic theme of creation" aria-describedby="creation" /><figcaption>‘Creation by Joshue 0 Connor (1993)</figcaption></figure>
然后在我的网页中,我可能会包含下面的段落,我可以将
id="creation"
分配给它。整个事情看起来就像清单 6-4 中的。***清单 6-4。*使用咏叹调的图像描述——描述者
`
Some Cosmic Artwork by Josh(2011) Sample of Pen and Ink Drawings
‘Creation’ by Joshue O Connor (1993) In a past life Josh was far more interested in playing guitars, painting, and in general larking about than he was with computers.Here is some more background about his artwork for those interested […]
This drawing illustrates the mystery of creation. It shows a large flaming triangle that holds a bright radiating sun at its apex, and a stylised smiling moon sits at its base in opposition. At the heart of the triangle there sits an exploding planet with the ancient Vedic symbol of creation the AUM at its heart. The image sits on a background framed of stars and small spaceships fly by randomly in the distance.
在 HTML 文档中找到的较长描述的例子稍微好一点。这种方法确实给了作者多一点呼吸的空间,也有希望还图像一个公道。是否是合适的描述,是否传达了图像同样的视觉丰富性?你是法官。可以说,图像功能越多,提供合适的替代文本就越容易,模糊性就越小。
最后,我的观点是,你通常不能用文字描述完全取代视觉媒介。但是,您可以使屏幕阅读器用户的用户体验更好。让体验变得更好也可以解读为“不那么可怕”。如果你发现你不知道如何描述某样东西,把图片分解成组成部分,或者找一个可能有帮助的完形视图或概述。如果都失败了,只要给图像一个空值
@alt
就不会影响用户体验。这是最后的手段,但在我看来,这比什么都不做并触发屏幕阅读器试探法要好。在我们转向更多功能代码等价物的不那么模糊的水域之前,只是为了说明提供有意义的描述有多么困难,我在图 6-4 “创造的种子”中提供了我的另一幅画你会如何描述这个?另外,向那些知道一些吠陀本体论的人道歉——梵天应该有四个头。是的,我确实有很多空闲时间。
图 6-4。“创造的种子”
这是一个简单的选择。
你可能想知道是否还能使用
@longdesc
来描述复杂的图像。在撰写本文时,longdesc
属性(或@longdesc
)已经过时,不再是 HTML5 规范的一部分。@longdesc
属性是一种在需要时提供更长的图像文本描述的方式,它已经被更好的技术所取代,比如我之前概述的那些技术。@longdesc
的使用采取以下一般形式:<p><imp src="some_complexgraphic.gif" alt="a complex image" longdesc="complex_image_description.html" /></p>
如您所见,
@longdesc
是一种链接到当前页面或另一个页面上的更长描述的机制。说浏览器和 AT 对它的支持很差可能有点过了,但支持肯定不是很好。它在学术界之外也很少使用。对于那些认为它有用的人来说,它是有用的——如果一个元素很好地服务于一个用例,即使它的应用不是完全通用的,我对保留或改进元素功能或在规范中保留一个元素没有问题。但那是我。然而,它确实有一些优势,尽管 ARIA 很棒,HTML5 也在许多领域取得了进步,但目前都没有提供对
@longdesc
的全功能替代。@longdesc
有一张王牌,它可以用来引用离页 URI,还可以提供结构化内容作为文本描述。不幸的是,它在浏览器中的实现和最终的用户体验往往还有许多不足之处。然而,这可能与其实现有关,而不是不需要一个更长的描述机制。这是 HTML 工作组中的一个热门话题,您可能会发现它正在重新浮出水面。类型 2:图形和图表
当图像是富含信息数据的图形或图表,难以用简单的
@alt
描述时,@alt
也可以用作一种描述性标签。该标签应给出图表旨在描述的内容的简要概述。记住图形和图表是使用
aria-describedby
等方法非常有用的完美场合,尤其是在页面可能包含已经与图像链接的更详细的概述的情况下。比如考虑图 6-5 。这是我在研究关于包容性设计的专业实践者使用的各种用户测试和评估方法的硕士论文时使用的图表。
***图 6-5。*测试和评估方法
为了提供图表的文字描述,我将给出图表视觉传达内容的概述。大概是这样的:
<img src="disability_types.png" alt="Most user testing is done with blind and vision impaired people, and the least with Deaf users and people with Dyslexia" />
考虑图 6-6 ,这个图表显示了用户测试的主要好处。有很多视觉信息要传达。在这种情况下,使用
aria-describedby
当然是更好的解决方案。***图 6-6。*用户测试的好处
您可能会发现,链接到网页正文中以更详细的方式概述调查结果的描述会更容易。这里我使用了
@alt
(作为一个短标签)和aria-describedby
的组合来进行更长的描述:<img src="benefits_of_usertesting.png" alt="Graph outlining the benefits of user testing" aria-describedby="benefit_test" />
然后在 HTML 文件的更深处,我可以有一个段落提供更丰富的描述,以及一些注释:
<p id=“benefit_test”> From this research we can see that practitioners feel some of the main benefit of user testing with people with disabilities is discovering usability issues with the interface, navigation, structure, functionality and so on. User testing as an awareness raising exercise for developers in order to first hand experience the diverse needs of people with disabilities and therefore gaining a greater understanding of how things work from the users perspective, is also an outcome of the research"</p>
对于图 6-7 ,它着眼于用户测试的规模,更容易描述。
***图 6-7。*测试组规模
<img src="test_sizes"alt="The majority of test group sizes are between 8 12 users." />
这是一个简洁的文本描述,但它完美地捕捉了图表中的视觉信息。有时候少即是多!
类型 3:文本图像
现在我们将处理本章前面提到的情况:图形设计师可能使用了用户机器上没有的 groovy 字体,而
@alt
被用作图像的替换文本。在这种情况下,@alt
应该清楚地说明样式文本是什么。例如,图 6-8 可以用作灯箱画廊或与吉他相关的图像集的图形标题,其中设计者希望使用特别风格化的字体。
***图 6-8。*一个图形标题
为了确保图像是可访问的,您可以如下所示对其进行标记:
<h1><img src="guitar_gallery.png" alt="The Guitar Gallery" /></h1>
注意像这样的大多数情况下,你只需在替换文本中镜像图像中的文本。下一个例子说明了为什么这种方法很重要。
图 6-9 是一个你可能在网站上看到的“特价”图片的例子。该图形旨在吸引眼球,并告知用户特价优惠。
***图 6-9。*图形中的文字
您可以按如下方式标记图像:
<img src="guitar_special_offers.png" alt="Special Offers on all guitars. Ends this Weds" />
如果没有替代文本,一个没有视力的人将不会知道商店正在出售他们的吉他,或者这只是一个限时优惠。也有一些情况下,一个标志可能包含一些文字或代表公司的身份。然后,您应该将公司名称作为替换文本添加到徽标图像中,而不是描述它的外观。假设图 6-10 链接到 HTML5 规范。
***图 6-10。*html 5 的 logo
你可以这样说,而不是像“新的 HTML5 标志看起来像一个大的橙色盾牌,中间有一个大 5”那样给图像一个替代的描述:
<a><img src="html5_logo.png" alt="For more on HTML5 specification, visit the W3C website" /></a>
这很好地引导我们进入下一种类型的图像,我在上一个例子中提到过:功能图像。
类型 4:功能性图像
当一个图像有一个特定的功能时,你应该使用
@alt
来描述它是做什么的,而不是它看起来像什么。想象一下,如果你在你最喜欢的吉他商场网站上看到了图 6-11 中的图片,并且访问它的唯一方式是通过图片本身的链接。
***图 6-11。*想赢得一把经典吉他吗?让它触手可及,每个人都有机会!
要使其可访问,您可以将其标记如下:
<a href="competition.html"> <img src="win_a_gibson.png" alt="Win a Classic Guitar..Click here to enter" /></a>
注我在一些网站上看到过这类图片,实际上进入比赛的唯一途径就是点击链接。因此,如果链接有某种目的,你可以描述它的目的,而不是它看起来像什么!没有什么比下面的例子更能说明这一点了。
图 6-12 。购买吉他的链接图
图 6-12 展示了一个按钮,顾客将用它来购买吉他。因此,没有必要提供类似以下内容的描述
<a><img src="buy_this_guitar.png" alt="Here is a nice graphic of a Gibson Guitar stylized with some creative Photoshop filters, and using a groovy font called Rosewood /></a>
不要。你只要说它的功能是什么——字面意思,“买这把吉他。”
<img src="buy_this_guitar.png"alt="Buy this Guitar" />
好了,这样好多了!所以坚持按下按钮。你甚至不需要包括像“点击这里”这样的文字,因为这是不必要的。屏幕阅读器将向用户宣布该图形是一个链接,用户将知道如何激活它。
类型 5:纯粹的装饰性图像
图像可能完全是装饰性的,不需要替代描述。为了不触发屏幕阅读器试探法,它需要对 AT 隐藏,因为它不会给用户体验增加任何东西。
您可以通过添加空值
@alt
来实现这一点,空值的形式为alt=""
(在“”之间没有空格),如下例所示:<img src="agroovy_but_semantically_useless_graphic" alt="">
我在这一章中已经多次提到这一点,但我将再次强调:明智地使用 null
@alt
可以增加用户体验,因为它可以用来消除大量的网页混乱。当被问到时,甚至许多有视力的人都会同意,许多网站的图形设计功能很差,有多余的混乱,或者它几乎没有给他们提供他们真正想要的功能!图像通常就在那里,占据空间,在某些情况下,实际上还会碍事。在可访问性社区中,关于哪些图像应该被描述,哪些不应该被描述的讨论没完没了。一个人的装饰图像是另一个人的艺术。这也取决于屏幕阅读器用户的偏好。有些人可能想要描述很多额外的东西;其他人(我认为是大多数人)很高兴去掉了很多杂乱的东西。
类型 6:图标
图像可以用作视觉线索或图标,也可以作为链接的一部分。图像本身实际上不应该是活动链接,因此应该在图像上使用 null
@alt
,而可以使用真实的 URL。在图 6-13 和它的同伴清单 6-5 中,内嵌图像被用作位于真实 URL 旁边的图标。
***图 6-13。*用作图标的内嵌图像
***清单 6-5。*内嵌图标代码
`
当屏幕阅读器将焦点放在刚刚显示的任何一个列出的链接上时,图像被忽略,而
<a>
元素的内容被公布。有时你会发现链接功能的重复,图标和真正的链接文本都是可点击的。尽量避免这样做,因为这对屏幕阅读器用户来说是一种痛苦。当他们浏览一个菜单时,他们会得到一个链接的副本。对于一个有视力的人来说,如果图标和旁边的 URL 是活动的可点击链接,用户可以很容易地选择其中之一。图标具有视觉上强化控件目的或以某种方式帮助理解的效果。这种视觉强化就是视觉。
图像颜色对比
除了提供有意义和管理良好的描述,确保您的图像——尤其是文本图像——具有足够的颜色对比度也非常重要。有很好的工具可以帮助你做到这一点,比如 WAT-C 色彩对比分析仪。可以在
[www.paciellogroup.com/resources/contrast-analyser.html](http://www.paciellogroup.com/resources/contrast-analyser.html)
拿到。HTML5 和可访问的<视频>和<音频>
HTML5 最大的进步之一是能够在浏览器中播放音频和视频,而不需要任何第三方插件,如 Flash、QuickTime 等。HTML5 视频是一个非常热门的话题。这对作为设计师的你会有什么影响,对用户体验又意味着什么?
HTML5 <视频>,<音频>,还有你
作为一名设计师,新的 HTML5
<video>
元素比我们以前做视频的方式有很多优势。不再有繁琐的代码和担心是否使用<embed>
或<object>
,我希望,作为一个设计师,有一个更有凝聚力的体验。话虽如此,在技术领域中,“进步”通常意味着你用一套全新的技术来替换曾经的技术。不幸的是,尽管 HTML5<video>
真的很棒,并提供了丰富和可访问的(如果做得好)用户体验,但它仍然很复杂。首先,您仍然需要处理不同浏览器支持的各种编解码器。对于官方支持的 HTML5 编解码器还没有达成共识,所以您有几个选择,您必须进行一些功能检测和巧妙的编码,以确保您为正确的浏览器提供正确的内容。如果只有一两个浏览器就好了,但所有浏览器都在争夺位置,每个制造商都支持(或不支持)自己的各种首选格式,以努力实现他们渴望的全球主导地位。
注整个“苹果不支持 Flash”的姿态是/是一场格式战。
HTML5 <视频>和你的用户
HTML5 视频有能力创造良好的无障碍播放器。这是个好消息。您可以使用本机控件或编写自己的脚本。我将很快向你展示如何构建你自己的无障碍播放器。
您还可以通过一些准备和跑腿工作,为您的电影创建自己的音频描述、说明和字幕。我们还将看看如何做到这一点。
【Flash 怎么了?
Flash 其实没什么问题。从可访问性的角度来看,它有很多优点,包括丰富的 API 和在创作环境中从语义上轻松描述大多数对象的能力。更加数据库驱动的平台 Flex 能够创建一些优秀的、可访问的富互联网应用,供有视觉障碍的人、屏幕阅读器用户等使用。然而,许多开发人员就是不使他们的 Flash 内容具有可访问性。Flex 应用空间略有不同,许多 Flex 组件都有一定程度的开箱即用的可访问性。
该插件是第三方解决方案。它不是浏览器自带的,而且是专有的。然而,它看起来并没有消失。HTML5 并不是进入游戏领域的唯一技术;Adobe 已经有了通过虚幻引擎(UE3)开发 Flash 的计划。现在,您可以在 Flash 环境中玩丰富的 3D 游戏。因此,焦点肯定会从视频平台转移到丰富的沉浸式游戏平台。
Flash 中的可访问性问题
如果您使用的是较新的屏幕阅读器,只需开发人员稍加努力,许多 Flash(尤其是 Flex 内容)都是可以访问的。然而,从可访问性的角度来看,Flash 存在一些实际问题(这可能是因为它不是“浏览器固有的”技术)。最明显的问题是无法使用键盘轻松地切换到 Flash 视频内容,还有一个相当反常的问题是无法切换出来(即使您设法进入了)。具有讽刺意味的是,这在 Internet Explorer 中并不是一个问题,但它确实会影响大多数其他浏览器。解决方法很复杂,因为您必须使用脚本来阻止用户返回。
打造无障碍播放器
在 HTML5 中构建一个可访问的
<audio>
或<video>
播放器是一个大杂烩。构建它们的某些方面确实很容易,但其他方面可能需要很好的脚本知识和一些 CSS 知识。(所需的脚本水平可能会让一些人望而却步,但我建议坚持下去。)可惜在某些方面还是有点棘手。然而,在许多方面,它并不像听起来那么令人生畏。你如何对待它,你想让它做什么,等等都是需要考虑的重要因素,它们将决定你需要投入多少努力才能得到一个可行的结果。
首先:嵌入式内容有什么新特性?
当您想要在 HTML5 页面中嵌入视频时,可以添加
<video>
元素。“就这些吗?”我听到你哭泣。“是的,”回答是。清单 6-6 中的简单代码调用了浏览器中的
<video>
元素。图 6-14 、 6-15 和 6-16 显示了结果。***清单 6-6。*调用<视频>元素
`
Sample native browser controls ` ***图 6-14。*火狐原生视频控件
***图 6-15。*戏曲原生视频控件
图 6-16。 Safari 本地视频控件
<video>
元素有一些属性可以通过 Media Elements API(即将推出)来访问,但仅此而已。<视频>回退内容
您在
<video>
元素中包含的任何内容都被视为后备内容。这是将由不支持视频的用户代理看到的内容。你应该仔细考虑你在里面放了什么,这样至少是有用的,而不是粗鲁的(在“你的浏览器不支持这个”或类似的无用信息的意义上)。回退内容可以是一些文本和指向备用可访问版本的链接,甚至是指向不同文件格式的链接列表。给用户一个选择总是好的,但是不要给他们太多的信息。注意我们在这里讨论的回退内容原则上同样适用于
<audio>
元素内容。查看[
camendesign.com/code/video_for_everybody](http://camendesign.com/code/video_for_everybody)
了解如何使用 Flash 视频作为后备内容。媒体元素 API
因此,您希望在 HTML5 页面中包含一些视频——通过向页面添加
<video>
元素来实现。<video>
元素的公共属性是src, preload, autoplay, mediagroup, loop, muted,
、controls, crossorigin,
和poster
。所有这些属性都非常符合你的期望。具体情况如下:src
属性:src
属性是视频或音频文件的来源。如今,利用crossorigin content
属性,媒体可以在许多不同的服务器上广泛传播。此属性与不同服务器之间的资源共享有关,是减少分散内容的安全顾虑和问题的一种方式。preload
属性:preload
属性有各种与之相关的关键字或状态。这些是none, metadata
,和auto
。preload
属性决定了浏览器在页面加载时如何在后台加载(或不加载)源材料。poster
属性:poster
属性对于在等待用户输入时显示合适的图像非常有用,这样用户在点击播放之前就不会看到空白屏幕。它实际上是一种未来的海报。mediagroup
属性:mediagroup
属性用于将几个音频或视频元素或轨道分组在一起,这对于视频和音频的播放列表很有用。- **
controls
属性:**这是一个布尔。它告诉浏览器显示控制媒体所需的本机控件,如播放、停止等。如果没有此属性,您必须提供自己的脚本控件。 - **
autoplay
、loop
、muted
属性:**他们完全按照罐头上说的去做。
注意浏览器提供的控件通常不能开箱即用,除非你使用 Opera 浏览器。Opera 开箱即用,提供了出色的键盘可访问性,因此您可以播放、暂停和改变视频或音频的音量。不幸的是,按照大多数其他标准,Opera 不是一个非常屏幕友好的浏览器,但就 HTML5
<video>
和<audio>
的原生键盘访问而言,它应该低头。入门<视频>
开始使用
<video>
元素很容易,您可以很快在浏览器中看到一些结果,并使用我刚刚介绍的 Media Elements API 属性定义一些基本属性。最初的步骤可能类似于清单 6-7 中的。***清单 6-7。*使用<视频>
`<video width=“700” height=“500” preload controls poster=“…/img/mayer_cc_poster.jpg”>
// Fallback content hereCan't access this video content?
Please visit the Creative Commons website for a format that suits you, or if you are happy with Flash content, visit the Flash version of the Mayer and Bettle creative Commons video
`从清单 6-7 中的代码可以看出,您已经调用了三个 API 属性来在浏览器中执行一些魔法:
preload
,预加载内容但不播放。controls
,要求浏览器显示原生浏览器控件。poster
,显示图像,直到视频播放完毕。这很有用,因为根据您的浏览器,您可能有一个空白或透明的空间,甚至可能看不清楚视频播放器控件。
我们还定义了视频的尺寸,并要求浏览器显示本地浏览器控件。
该示例有四种不同的视频源或视频类型,具体取决于访问内容时使用的浏览器。为每个浏览器提供正确的编解码器可能相当复杂,您需要手头上有一些视频转换工具,以便能够生成您需要的版本。这样做相对来说比较琐碎,但是可能比较耗时。你一个接一个地安排不同的视频格式和它们的源 URL 当浏览器点击它理解的内容时,它会预加载并播放它。如果浏览器不理解您提供的任何格式,这将触发嵌入在
<video>
和</video>
元素之间的回退内容的显示。一些编码工具
以下是一些对编码音频/视频媒体有用的工具列表:
- Audacity: 一个优秀的、免费的、开源的录音机。在
[www.audacity.sourceforge.net](http://www.audacity.sourceforge.net)
拿到。 - **Firefogg:**Firefox 的一个视频和音频编码应用。在
[www.firefogg.org](http://www.firefogg.org)
拿到。 - FFmpeg2theora: 一个 OggTheora 文件的转换器,可在
[
v2v.cc/~j/ffmpeg2theora/](http://v2v.cc/~j/ffmpeg2theora/)
获得。 - 手刹:开源视频转码器。在
[www.handbrake.fr](http://www.handbrake.fr)
拿到。
你是我喜欢的类型吗?
MIME 类型告诉浏览器 URL 指的是哪种媒体。将正确的 MIME 类型添加到
source
属性的末尾非常重要。(你可以在清单 6-7 中看到 MIME 类型。)有些浏览器对只播放附带的媒体相当严格,比如(Firefox 和 Opera)。一些最常用的音频文件格式及其对应的 MIME 类型如下:
- MP3: 音频/mpeg
- OGG: 音频/视频/ogg
- MP4: 音频/mp4 视频/mp4
- **网络视频:**音频/网络视频/网络视频
- WAV: 音频/wav
- AAC: 音频/3gpp,音频/3gpp2,音频/mp4,音频/MP4A-LATM,音频/mpeg 4-通用
表 6-1 概述了主流浏览器支持的音频格式。
注意当编解码器表示用于传送媒体的压缩/解压缩算法时,它也表示编解码器的容器。
表 6-2 涵盖了视频编解码器,以及每种编解码器支持哪些浏览器。
某些容器可以采用多种文件格式。(记住,编解码器既是算法,也是包装器,或者保存它的容器。)在
[
en.wikipedia.org/wiki/Comparison_of_container_formats](http://en.wikipedia.org/wiki/Comparison_of_container_formats)
你可以很好地了解容器的概况以及它们之间的比较。提示为了让你的内容能够以最少的格式创建和解码数量到达最多的浏览器,你应该至少提供两种格式的音频,比如 MP4 和 Ogg,至少提供三种最常用的格式的视频:MP4、WebM 和 Ogg。
让您的控制易于使用
注我要特别感谢我的朋友盖兹·莱蒙,以及马克·博厄斯和西尔维亚·菲弗,感谢他们在我编写这一部分时给予的慷慨帮助、评论和建议。
在某些方面,你已经看到了容易的部分。接下来您将看到的是添加您自己的控件,并使它们既可以通过键盘访问,也可以被屏幕阅读器用户访问。我们还将看看如何使向前跳和向后跳的功能,以及控制静音的音频。不幸的是,开箱即用,目前没有一种方法可以轻松做到这一点,所以你必须编写脚本并创建自己的。
注意最难的是脚本,但是如果你保持简单,你可以实现很多,并且不会在这个过程中失去理智。嗯,这可能不完全正确。此外,您可以只使用本机 HTML 输入控件,如按钮,然后添加脚本。这为您提供了更多的开箱即用的可访问性,但是您在样式选择上有点受限。对于手卷控件,您有更多的空间来随心所欲地设计它们的样式。
有很多方法可以用来开发控件,所以我们来看几个。显然,确保你的播放器是可访问的是非常重要的,以下所有内容都着眼于可访问性。在这里,我创建了自己的图形来表示控件,然后应用了必要的 JavaScript。您还可以使用 CSS 来创建按钮并设置其样式。无论哪种方式,JavaScript 都非常相似。
图 6-17 是我在 Photoshop 中创建的控件的屏幕截图,我将用它来控制我的视频。它们分别是播放、停止、静音和向前跳/向后跳。
***图 6-17。*视频播放器的一组手卷控件
首先,我将每个控件包装在一个
<div>
元素中,然后适当地命名它。在每个<div>
元素中,有一个image
元素和一个合适的@alt
文本值来描述控件。例如,以下是按钮控制:`
`在某些浏览器中,这些控件都可以通过键盘访问,当屏幕阅读器将焦点放在前面的控件上时,就会显示“播放按钮”。然而,您必须测试哪些有效,哪些无效。
注意在第一个例子中,我使用了#来通过键盘使控件成为焦点。传统上,使用#是为了给 JavaScript 一个焦点,但是随着 DOM 脚本的发展和像 jQuery 这样的工具包的普及,它并不总是必要的。如果您确实使用这个方法,一定要在它后面添加
“return false();”
语句,因为这会阻止“#”
URL 触发。清单 6-8 显示了所有控件的代码。首先,您将处理播放、停止和静音按钮。
***清单 6-8。*实现视频控制
`
`使控件可聚焦并附加播放、停止和静音/取消静音等方法所需的 JavaScript 相当简单。我暂时忽略了向前和向后的控制;我们以后再看这些。研究清单 6-9 ,看看你是否能理解它。
***清单 6-9。*视频控制焦点的 JavaScript】
`
window.οnlοad=function(){
var video = document.getElementById(‘access_video’);
var play = document.getElementById(‘play’);
var stop = document.getElementById(‘stop’);
var mute = document.getElementById(‘mute’);// Script needed to attach the onclick events with the functional buttons
// Remember even though the event is called onclick it still works from //
// the keyboardplay.onclick = playVideo;
stop.onclick = stopVideo;
mute.onclick = muteVideo;// function to play, pause, mute etc
function playVideo() {
video.play();
}
function stopVideo() {
video.pause();
}// This function allows the button to be used as control to
// toggle the audio on or offfunction muteVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.muted = !video.muted;
}`注意使用 iKeyCodes 确保
muteVideo
功能仅由回车键或空格键触发。还有一些简单的 CSS 声明将整个事情放在一起:
<style> #player_controls { color:#999; margin: 10px; border:10px; float:left; } </style>
无障碍 HTML5 视频播放器版本 1
清单 6-10 给出了全部代码,包括向前跳和向后跳按钮所需的代码。
***清单 6-10。*无障碍播放器 V.1
`
Working HTML 5 video player var video = document.getElementById(‘access_video’);
var play = document.getElementById(‘play’);
var stop = document.getElementById(‘stop’);
var mute = document.getElementById(‘mute’);
var forward = document.getElementById(‘forward’);
var back = document.getElementById(‘back’);// Script needed to attach the onclick events with the functional buttons.
// Remember even though the event is called onclick it still works from the
// keyboard.play.onclick = playVideo;
stop.onclick = stopVideo;
mute.onclick = muteVideo;
forward.onclick = jumpForward;
back.onclick = jumpBack;// Duplicate onkeydown events for keyboard a11y
play.onkeydown = playVideo;
stop.onkeydown = stopVideo;
mute.onkeydown = muteVideo;
forward.onkeydown = jumpForward;
back.onkeydown = jumpBack;// New function for play
function playVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.play();
}// New function for pause
function stopVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.pause();
}// This function allows the button to be used as a control to
// toggle the audio on or off.function muteVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.muted = !video.muted;
}// Jump forward, Jump Back
forward.onclick = jumpForward;
function jumpForward(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.currentTime = video.currentTime + 15;
video.play();
return false;
}back.onclick = jumpBack;
function jumpBack(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.currentTime = video.currentTime 15;
video.play();
return false;
}};
Oops cannot access this video content? Never fear!
Please visit the Creative Commons website for a format that suits you
`图 6-18 显示了你的第一个版本的无障碍播放器的屏幕截图。
图 6-18 。无障碍视频播放器
好吧,不是很刺激,但是很管用。然而,你可以做一些事情来改善各方面的情况。
可访问的 HTML5 视频播放器版本 2
上一个示例中的代码存在一些问题。首先,如果 JavaScript 关闭或不可用会发生什么;使用#是个好主意吗?好吧,在显式控件的情况下,这一点有点不切实际。这是因为即使你想创建一个不引人注目的控件,这样做回避了你可以指向什么作为替代的问题,因为控件的目的是播放一些视频。在前面的示例中,对回退内容有一些很好的规定。如果不支持 HTML5,用户可以将浏览器指向该网站并下载内容。
你可以做一些事情来提高球员的水平。首先,您可以用“#”删除空 URL,将它们改为
<divs>,
,使它们可以从键盘获得焦点,并添加一些 ARIA 角色属性。注意现在 JavaScript 保持不变。稍后您将看到为前进和后退功能以及其他一些控件添加脚本。
让我们来看看新代码:
`<div id=“play” tabindex=“0”>
`
<img src=“player/play_button.png” alt=“Play Button” role=“button” />这里的主要变化是增加了 ARIA
role=“button”
属性,它告诉屏幕阅读器和浏览器<div>
的用途是什么。通过添加tabindex=“0”
值,您还可以从键盘访问<div>
。所以这是两方面的胜利!这两个属性都应该应用于所有控件。我还添加了以下代码,以确保控件将在键盘上突出显示焦点:
*[tabindex]:focus { outline:none; border: solid yellow 2px; }
注意关于使用 URL #作为关注控件的方式或者使用
<div>
和tabindex="0"
的方式,你需要在尽可能多的不同浏览器中测试这两种方法。一些开发人员喜欢#方法,另一些开发人员喜欢带有tabindex
的<div>
,尽管后者现在得到了很好的支持。这个例子的 JavaScript 代码(实际上同时使用了 a #和 tabindexed
<div>
)非常简单,但是当它最终工作起来的时候,一切看起来都很简单!看看你是否能弄清楚清单 6-11 中发生了什么。
***清单 6-11。*添加播放、停止、静音、前进和后退功能的代码
`window.οnlοad=function(){
var video = document.getElementById(‘access_video’);
var play = document.getElementById(‘play’);
var stop = document.getElementById(‘stop’);
var mute = document.getElementById(‘mute’);
var forward = document.getElementById(‘forward’);
var back = document.getElementById(‘back’);// Script needed to attach the onclick events with the functional buttons.
// Remember even though the event is called onclick it still works from the
// keyboard.play.onclick = playVideo;
stop.onclick = stopVideo;
mute.onclick = muteVideo;
forward.onclick = jumpForward;
back.onclick = jumpBack;// Duplicate onkeydown events for keyboard a11y
play.onkeydown = playVideo;
stop.onkeydown = stopVideo;
mute.onkeydown = muteVideo;
forward.onkeydown = jumpForward;
back.onkeydown = jumpBack;// New function for play
function playVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.play();
}// New function for pause
function stopVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.pause();
}// This function allows the button to be used as a control to
// toggle the audio on or off.function muteVideo(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.muted = !video.muted;
}// Jump forward, Jump Back
forward.onclick = jumpForward;
function jumpForward(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.currentTime = video.currentTime + 15;
video.play();
return false;
}back.onclick = jumpBack;
function jumpBack(objEvent) {
if (objEvent.type == keydown’)
{
var iKeyCode = objEvent.keyCode;
if (iKeyCode != 13 && iKeyCode !=32) {
return true;
}
}
video.currentTime = video.currentTime 15;
video.play();
return false;
}};
`
控件本身的代码如清单 6-12 所示。
***清单 6-12。*使用 tabindex="0 "将功能附加到定制的控件上,以关注一个< div >,而不是使用#
`
在
[
techrecord.net/html5/HTML5_video_player_no_captions_final.html](http://techrecord.net/html5/HTML5_video_player_no_captions_final.html)
可以看到播放器的工作版本。接下来,我们将看看如何给视频添加字幕。
注意如果所有这些都太多,还有现成的视频播放器可以使用,比如用于视频的 jPlayer 和 jQuery UI。您可以分别在
[
jplayer.org](http://jplayer.org)
和[
github.com/azatoth/jquery-video](https://github.com/azatoth/jquery-video)
访问它们。带有<轨道>元素的音频描述和字幕
如果你想对你的视频文件做各种各样的音频描述或者标题,HTML5 有一个新的元素叫做
<track>
元素。表 6-3 概述了你可以用新元素做什么。表 6-3。媒体元素概述 ?? 1T5
1
要在您的视频内容中使用标题、副标题或章节信息,您可以通过
kind
属性添加它们。src
属性指向文本存储的位置,srclang
属性定义文本使用的语言,label
属性给出标题。清单 6-13 详细说明了正确的用法。**清单 6-13。**给<轨道>元素添加字幕
<video src="brave.webm"> <track kind="subtitles src=brave.en.vtt" srclang="en" label="English"> <track kind="captions src=brave.en.hoh.vtt" srclang="en"label="English for the Hard of Hearing"> <track kind="subtitles src=brave.fr.vtt" srclang="fr"lang="fr" label="Français"> <track kind="subtitles src=brave.de.vtt"srclang="de" lang="de" label="Deutsch"> </video><sup>2</sup>
原则上,添加音频描述和/或字幕非常简单,对吗?好吧,如果你最喜欢的浏览器支持这种东西,那就可以了,但目前还不支持(在我写这篇文章的时候),但这将会改变。为了实现这一点,我使用了开源的 JavaScript 库 Captionator,发现它工作得非常好。
2 从
[
dev.w3.org/html5/spec-author-view/the-track-element.html](http://dev.w3.org/html5/spec-author-view/the-track-element.html)
注你可以在
https://github.com/cgiffard/Captionator
下载 JavaScript 库,获取更多关于 Captionator 的信息。将它添加到您的视频中就像将以下脚本添加到您的页面中一样简单:
`
`然后通过添加以下内容来启用它:
captionator.captionify(document.getElementByID("video"));
就这样。我可以继续使用 Text Wrangler 编写. vtt 文件来创建标题本身。那个。vtt 文件格式易于使用——只需打开您最喜欢的编辑器,并使用扩展名保存您创建的文件。vtt 。
提示设置
有许多不同的提示设置供您使用。详见表 6-4 。
入门相当容易。图 6-19 显示了我的视频字幕文件。您可以定义标题或副标题出现的开始和结束时间,然后使用提示设置告诉浏览器大小、对齐方式等。请看下面我的截图。我用来给视频加字幕的 vtt 文件。并做实验。奇怪的是,这是一项引人注目的工作,相当耗时,但也很有趣。
***图 6-19。*样本 VTT 文件
注意要了解更多关于 VTT 的信息和一篇好文章,请看一下
[
www.iandevlin.com/blog/2011/05/html5/webvtt-and-video-subtitles](http://www.iandevlin.com/blog/2011/05/html5/webvtt-and-video-subtitles)
上伊恩·德夫林的有用概述。您可以在图 6-20 中看到带字幕视频的视频播放器截图,并在
[
techrecord.net/html5/HTML5_video_player_captions_final.html](http://techrecord.net/html5/HTML5_video_player_captions_final.html)
上线试用。***图 6-20。*无障碍播放器字幕视频截图
注欲了解更多关于具有良好可及性角度的 HTML5 视频的信息,请参见 Silvia Pfeiffer 的新书,html 5 视频权威指南 (Apress,2010)。
创建一个<音频>播放器
这只是一个简短的说明,说明创建一个音频播放器更容易一些,你所学到的关于制作播放器的知识(比如创建你自己的控件等等)也适用于音频播放器。
<画布>无障碍
动态渲染动态位图图形的 2D 绘图 API 可以用来在浏览器中创建一些非常好的视觉动画(甚至更多),而不需要任何插件。有许多 groovy 测试案例和网站非常成功地全部或部分使用了
<canvas>
。然而,从可访问性的角度来看(为了让每个人的生活更容易),除了漂亮的图片,不要使用<canvas>
。在撰写本文时,它还不能被认为是可访问的。在万维网联盟(W3C)的幕后有大量的工作在进行,并努力使之成为现实。然而,在我看来,如果有另一种开发内容的方式更合适,你应该使用它。事实上,规范对此有如下建议:"当有更合适的元素可用时,作者不应在文档中使用 canvas 元素。例如,使用 canvas 元素来呈现页面标题是不合适的:如果想要的标题呈现在图形上很强烈,就应该使用合适的元素(通常是 h1)来标记,然后使用 CSS 和支持技术(如 XBL)来设计样式
当作者使用 canvas 元素时,他们还必须提供内容,当呈现给用户时,传达与位图 canvas 基本相同的功能或目的。该内容可以作为 canvas 元素的内容放置。canvas 元素的内容(如果有)是元素的后备内容。4
使用
<canvas>
开发了各种本不该开发的东西。文本编辑器 Bespin 在我脑海中是一个看起来不错的工具,但实际上可能永远也不会被使用。注您可以在
[
benzilla.galbraiths.org/2009/02/17/bespin-and-canvas](http://benzilla.galbraiths.org/2009/02/17/bespin-and-canvas)
查看 Bespin。在很多方面,它令人印象深刻,但我认为它使用了错误的工具作为基础。顺便说一下,我认为
<canvas>
的其他一些非常聪明的用法(不考虑可访问性)是:- **SoundManager 2 / 360 播放器演示:**可在
[www.schillmania.com/projects/soundmanager2/demo/360-player/](http://www.schillmania.com/projects/soundmanager2/demo/360-player/)
获得。这太棒了,这些好心人也给你看看源代码。 - **9 元素:**在
[
9elements.com/io/projects/html5/canvas/](http://9elements.com/io/projects/html5/canvas/)
可用。它有很好的鼠标交互和很棒的音调交互! - 一个字体生成器和一个可能的 sIFR 替代品。在
[
cufon.shoqolate.com/generate/](http://cufon.shoqolate.com/generate/)
可用。Roger Johannes 在[www.456bereastreet.com/archive/200905/cufon_and_screen_readers/](http://www.456bereastreet.com/archive/200905/cufon_and_screen_readers/)
撰写了关于 Cufón 和屏幕阅读器的文章。 - 有一个很好的列表,列出了使用
<canvas>
开发的游戏、小工具等等,可以从[www.w3.org/html/wg/wiki/AddedElementCanvas](http://www.w3.org/html/wg/wiki/AddedElementCanvas)
获得。在这里你还可以找到很多关于<canvas>
的讨论链接,以及当试图让这个绘图 API 更容易使用时所面临的挑战。
话虽如此,
<canvas>
仍处于起步阶段,从可访问性的角度来看,它面临着巨大的挑战。例如,它没有 DOM,那么屏幕阅读器如何生成文档的概览呢?如果你继续使用<canvas>
来吸引眼球,你会没事的。HTML5 有许多很棒的工具来构建可访问的东西,并为许多具有不同能力的用户组提供丰富的用户体验。所以当你需要勺子的时候,用勺子。虽然有人会说,“没有勺子。”
4
注意如果你想要一个很好的参考来创建你自己的
<canvas>
视觉糖果,我推荐 Nihilogics HTML5<canvas>
备忘单,它可以在[www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.pdf](http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.pdf)
获得。结论
在这一章中,我们看了很多可以让 HTML5 富媒体更容易访问的新方法。有许多基于您过去如何使用 HTML 4 做事情的最佳实践,您仍然可以应用,但也有一些新的技巧,我希望本章已经让您喜欢上了。在下一章,我们将看看如何使用 HTML5 来访问数据表。
七、HTML5 和可访问的数据表
在这一章中,你将学到所有你需要知道的关于使用 HTML5 创建简单和更复杂的可访问数据表的知识。
数据表通常用作可视化呈现表格数据的方式。这些数据可以是作者感兴趣的任何内容。表格布局允许作者呈现信息,以便网站用户可以轻松地将任何给定单元格中的数据与各种类别或关系相关联,这些类别或关系通常在每一列或每一行的开头定义。
这通常是在我们许多人常见的布局中完成的,单个数据单元格与不同的列和行相关。网站的用户可以查看各个数据单元格,并快速浏览以查看它们涉及哪些列和行。然后,他们可以快速理解每个单元格中的数据的含义。
桌子的麻烦
对于一个有视力的人来说,弄清楚这些关系是简单明了的,而且往往发生得非常快。如果一个表格设计得很好,那么首先会使理解这些关系变得更容易,大多数视力正常的用户在理解它们时不会有问题。他们首先关注表数据是什么——换句话说,它与什么主题相关——然后确定表中包含的信息实际上意味着什么。
对于一个没有视力的人来说,成功地完成这两个步骤需要开发者做更多的工作。这有几个原因,但主要是因为当一个表格显示在浏览器中时,视力正常的用户通常会很快得到这些关系。一个没有视力的用户将以一种非常不同的方式访问表中的数据——以线性方式,一项接一项地访问。
在一个失明的人甚至开始调查或询问(我喜欢使用这个术语,因为它与数据表和可访问性相关)数据表之前,她首先需要一种方法来容易地理解表的用途。这归结为用户在问,“这张桌子是做什么用的?”,赶紧接着问“这是什么意思?”
屏幕阅读器和数据表
创建一个视力正常的人能够容易理解的表是相当容易的(只要你试图表示的初始数据是简单明了的)。您为每一列创建一些标题,也许为它们添加粗体样式,然后添加行,也许为每一行的第一项添加粗体样式。很简单。如果这是一份纸质文件,那就好了。
然而,要使一个数据表在 HTML5 中可访问,你必须想办法以编程方式定义数据单元格和它们相应的列和行之间的关系。这样做有助于像辅助技术(AT)这样的用户代理理解数据单元及其对应的列和行之间的关系,因此它使 AT 能够以用户可以理解的方式通知失明的用户。
*对于屏幕阅读器的用户来说,HTML5 语言有定义这些关系的方法,因此首先使数据表易于理解,其次便于导航,然后,如果表与用户的需求无关,则跳过它。
注一个屏幕阅读器是一个线性输出设备。这意味着它一次向用户输出一部分信息。对于一个没有视力的用户来说,如果他对 HTML 内容有一个完形的看法,你需要使用适当的代码来帮助他。这通常是通过编写内容的文本概述并以编程方式将其与表格相关联来实现的,以便当表格获得焦点时会显示出来。在这一章的后面我会详细说明如何做到这一点。
数据表的常见模式
您可能要创建的大多数数据表都很简单,并且在形式上遵循一条老路。我可以听到你愤怒地大叫,“你是说我不会创建复杂的、多列的不规则数据表吗?”是的,我是。您创建的表可能有更多或更少的列或行,但它们主要是一个基本的网格,在列和相应行的顶部有标题。
它们可能采用表 7-1 中所示的形式。
桌子可能是正方形或长方形的,虽然并不总是这样,但总的来说,你的桌子将采用表 7-1 所示的形式。因此,我们将研究的使表格可访问的技术将同样适用于刚刚显示的简单表格和具有大量列和行的表格。在这种情况下,大小并不重要。
你需要能够做两件事。首先,对于视力正常的视觉用户,您需要创建表格,以便他们可以看到表格顶部的信息(标题信息),然后,通常是每行的第一列。然后,他们可以查看整个表,为每个数据单元格建立必要的关联。通过这样做,他们可以看到每个单元格中的数据与什么相关。
其次,为了让屏幕阅读器用户能够访问这些表,您需要使用 HTML5 将每个单元格中的数据与其对应的列标题和行相关联,以便屏幕阅读器本身可以向用户通知哪个标题与每个数据单元格相关。
使用 HTML5 正确标记数据单元格实现了两个实用功能。首先,它通知屏幕阅读器用户当每个单元格有焦点时它所涉及的列和行的组合;第二,它允许用户在浏览表格时了解自己在表格中的位置。
屏幕阅读器用户可以使用光标键轻松地在数据单元格之间导航。我在本章剩余部分展示的内容将帮助您通过简单的步骤使您的表真正可访问。
TMI?
在我们研究如何使您的数据表可访问之前,我建议您执行以下操作:
- 首先,尽量使数据表尽可能简单。如果表很复杂和繁忙,代码也会很复杂。尽管创建复杂的可访问的表是可能的,但是如果您能够首先简化表的架构,这将会很有帮助。
- 尽量不要跨越多个单元格/行。同样,一个更简单、外观更好的表通常更容易访问。
- 最后,考虑下面这个问题:你要展示的信息能包含在你网站的正文中吗?换句话说,你真的需要一张桌子吗?
如何创建可访问的表格
图 7-1 ,你将在本章的后面看到,显示了一个表格,它扩展了本书其他一些例子中出现的“动物避难所”主题。该表概述了即将在我们的动物保护区举行的研讨会。
好吧,首先。如前所述,一个有视力的人可以看着桌子,从一开始就知道它是什么。你怎么能为一个没有视力的人做这些?答案是,通过添加一个
<caption>
元素。元素是给视力正常的用户和屏幕阅读器用户一种理解表格用途的方式。HTML5 规范将
<caption>
元素描述为提供表格的标题。这是一个不错的思考方式。添加<caption>
元素很容易,添加到<caption>
元素的任何文本字符串都是以编程方式将与表关联起来的*。一旦表格从屏幕上获得焦点,它将被通知给用户,而不需要更多的交互。这非常有用,是使数据表可访问的第一个重要步骤。它对视力正常的用户也有好处,因为它以可视化的方式呈现,并且可以使用 CSS 进行样式化。*将
<caption>
元素添加到数据表采用以下形式:`
Animal Sanctuary workshops
An overview of upcoming animal sanctuary workshops in 2012 […]
`使用表格的
<caption>
元素或标题有助于帮助屏幕阅读器理解表格是什么。如果你考虑一个有五个或六个(甚至更多)数据表的网页,以这种方式添加<caption>
真的很有用。一个有视力的人可以快速浏览网页,并找出所有这些表格是什么。如前所述,屏幕阅读器用户可以通过选择各种 HTML 元素——如标题和链接——使用 AT 来浏览网页。他们可以使用页面上的任何<table>
元素做同样的事情。例如,在 JAWS 中按下 T 键会导致 AT 将用户从第一个表跳到最后一个表(然后再跳回来)。如果每个表格上没有合适的<caption>
,屏幕阅读器只是宣布“table”、“table”,并让用户知道表格有多少行、列等等,但它不能告诉用户表格是做什么用的。添加<caption>
填补了空白。带有合适的<caption>
的数据表宣布焦点上的内容。因此,如果我建议的包含六个表的页面上的所有表都有<caption>
元素,屏幕阅读器用户可以很容易地找到她要找的东西——因为当每个表获得焦点时,<caption>
元素的内容就会被公布。整洁!提示当表格比较复杂时,可以给表格元素添加一个汇总属性(
@summary
)。该属性旨在为屏幕阅读器用户提供更复杂数据表的概述,但不幸的是,它现在在 HTML5 中已经过时了。我仍然认为@summary
非常有用,因为当屏幕阅读器用户关注一个表格时,它就会显示出来。我经常在我的项目中使用@summary
来提供补充信息,如果我认为它可以帮助用户理解表格,或者总的来说,有更好的用户体验。这稍微超出了它的设计范围,但是根据我的经验,它工作得很好。对于许多简单的数据表来说,@summary
并不是必需的,因为一个有用的<caption>
就足够了。@summary
对视力正常的用户是隐藏的,但会被屏幕阅读器发现。我认为
@summary
应该被保留和使用,但是 HTML5 工作组决定让它过时。我和可访问性社区的其他朋友和同事一起,反复提出保留它的理由——但是没有用。如果你想知道 grizzly 的细节,你可以看看工作组在[www.w3.org/html/wg/tracker/issues/32](http://www.w3.org/html/wg/tracker/issues/32)
的“问题跟踪器”中的日志,或者访问位于[www.w3.org/html/wg/wiki/SummaryForTABLE](http://www.w3.org/html/wg/wiki/SummaryForTABLE)
的 W3C ESW 维基。做这些事情包括通知屏幕阅读器用户表格是关于什么的。如何导航表格本身并理解哪个数据单元格与哪个列和行相关?
在数据单元格、表格标题和行之间创建编程关联
有几种常见的方法来标记 HTML5 表,使它们可访问,并且更向后兼容旧的 AT(有许多用户!).第一种方法是使用标题/ID 组合来标识每个表格单元格的内容。第二种方法使用头/范围组合。
可访问的表方法 1:使用标题/ID 组合
我们要看的第一种方法稍微费时一些,但我认为它更可靠。我们将在表格 HTML 的
header
和ID
元素之间创建关联。这是一种将数据单元格的内容与其相应的标题相关联的方式。这样做将导致屏幕阅读器在向用户宣布单元格的内容之前宣布数据单元格在的哪一列。要创建标题/ID 关联,首先要处理标题,然后处理表体。
从给每个标题一个唯一的 ID 开始;给标题一个与内容相同的 ID 是完全可以的。关于我的动物保护区即将举办的研讨会,我的标题标识如下:
- Header #1 = “课程”
- 标题#2 = “开始”
- 标题#3 = “结束”
- 标题#4 = “成本”
- Header #5 = "Extras "
在 HTML 代码中,标题如下所示:
`Course
Start Date End Date Cost`Additional content included in 它可以是以下内容或类似内容:
`Course
Start Date End Date Cost Included Extras`如果您对任何命名约定感到满意,您当然可以使用它。关键是标题 id 是唯一的,因为它们用于创建与表数据的编程关联(正如您将看到的)。对我来说,他们有关系似乎更自然,但这并不重要。现在您已经有了合适的标题 id,接下来您可以将表体中每一行的单元格内容映射到一个合适的标题,如清单 7-1 所示。
清单 7-1 。映射单元格内容
`Course
Start Date End Date Cost Included Extras How do you start an Animal Sanctuary June 10 June 16 650 Euros includes lunches, one dinner and extensive materials. Working with Dogs: A beginners workshop April 12 April 16 300 Euros includes lunches, and materials.[…]`
使用标题/ID 组合的最终可访问表
通过查看清单 7-1 中的例子,你能看出标题和数据单元内容之间的关联是如何建立的吗?
图 7-1 是决赛桌的屏幕截图。
图 7-1 。可访问数据表示例
清单 7-2 显示了最终完全编码的样本(也有合适的
<caption>
元素)。清单 7-2 。可访问表方法 1 的最终表代码
`
Animal Sanctuary workshops
`An overview of upcoming Animal Sanctuary workshops in 2012 Course Start Date End Date Cost Included Extras How do you start an Animal Sanctuary June 10 June 16 650 Euros includes lunches, one dinner and extensive materials. Working with Dogs: A beginners workshop April 12 April 16 300 Euros includes lunches, and materials. Massage for You & Your Animals September 29 October 4 400 Euros. A Half day session is 220 Euros. includes lunch, and book. Yoga with Animals May 18 May 21 300 Euros includes lunch, dinner and book. A Creative Artistic workshop and Retreat June 18 June 23 500 Euros includes lunch, dinner and art supplies. Why Compassion for Animals matter: Philosophy and Animals July 12 July 14 200 Euros includes lunch, and materials Sanctuary Basics September 22 September 24 275 Euros. includes lunch, and class materials 可访问的表方法 2:使用头/范围组合
标记同一个表的另一种方法是将表头与
scope
属性(@scope
)结合使用。HTML5 规范是这样描述使用标题/范围组合构建数据表的:- 第一行中的标题都直接应用于其所在列中的行。
- 具有显式范围属性的标题适用于其行组中的所有单元格。
- 其余的标题只适用于它们右边的单元格。
这意味着您可以拥有不规则的表格,这些表格仍然被认为是简单的,但是它们可能具有不应该包含在特定行中的标题,或者它们可能具有包含几列的行。
规范给出了清单 7-3 中的例子。请注意,在这种情况下,具有显式范围属性的标题应用于其行组中的所有单元格,而不是第一列中的单元格。另请参见新的 HTML5 语法,即对于
<th>
、<td>
或<tr>
元素不使用结束元素,或者对于任何单元格值不使用引号。如果您愿意,您仍然可以用旧的方式编码。您还可以看到新的<thead>
(表头)和<tbody>
(表体)元素,它们几乎如其名称所表示的那样,允许您在表格中表示内容块。还有一个<tfoot>
(表尾)元素,这里不做展示。清单 7-3 。使用范围属性
`
`ID Measurement Average Maximum
Cats
93 Legs 3.5 4
10 Tails 1 1
English speakers
32 Legs 2.67 4
35 Tails 0.33 1 清单 7-3 中的代码产生了图 7-2 中的表格,这稍微复杂一些。
图 7-2 。HTML5 规格数据表示例
th
元素可以指定一个scope
内容属性。scope
属性有以下五种状态(带有特定的关键字):row
关键字,它映射到行状态。行状态意味着标题单元格应用于同一行中的一些后续单元格。col
关键字,它映射到列状态。列状态意味着标题单元格应用于同一列中的一些后续单元格。rowgroup
关键字,它映射到行组状态。行组状态意味着标题单元格适用于行组中所有剩余的单元格。colgroup
关键字,它映射到列组状态。列组状态意味着标题单元格适用于列组中所有剩余的单元格。- 自动状态。auto 状态使标题单元格应用于基于上下文选择的一组单元格。
图 7-3 来自 HTML5 规范。它直观地展示了算法是如何工作的。
图 7-3 。HTML5 范围算法的可视化 1
从顶部直向下指的四个箭头代表表格标题——“ID”、“Measurement”等,并显示它们与其对应行的所有内容相关联。表格标题(
<th>
)的出现以及它与相关行中所有数据单元格的关联得到了大多数浏览器和的良好支持,甚至比更早的。这种基本的编程关联对表的可访问性有很大帮助。对于屏幕阅读器用户来说,它是如何工作的:当用户遇到具有适当标题的表格时,她使用光标键在数据单元格中导航,首先宣布表格标题是什么,然后宣布数据单元格的内容。其他箭头显示了前面示例中应用的
@scope
元素如何与其行中剩余的单元格相关联,以及这些单元格如何应用于其右侧的单元格。使用标题/范围组合的示例
如果您将 header/scope 方法应用于我们的表,标记将类似于清单 7-4 中所示的内容。
1
注意在 HTML5 中,
td
元素上的 scope 属性已经过时。在 HTML 4 中,您曾经可以将它添加到一个<td>
单元格中,但是如果您想要有效的 HTML,您就不能再这样做了。(我将在第十章“工具、提示和技巧:评估你的可访问 HTML5 项目”中讨论验证问题。)对于 HTML5 数据表,请在th
元素上使用 scope 属性。清单 7-4 。使用标题/范围方法
`
Animal Sanctuary workshops
`An overview of upcoming Animal Sanctuary workshops in 2012 Course Start Date End Date Cost Included Extras How do you start an Animal Sanctuary June 10 June 16 650 Euros includes lunches, one dinner and extensive materials. Working with Dogs: A beginners workshop April 12 April 16 300 Euros includes lunches, and materials. Massage for You & Your Animals September 29 October 4 400 Euros. A Half day session is 220 Euros. includes lunch, and book. Yoga with Animals May 18 May 21 300 Euros. includes lunch, dinner and book. A Creative Artistic workshop and Retreat June 18 June 23 500 Euros includes lunch, dinner and art supplies. Why Compassion for Animals matter: Philosophy and Animals July 12 July 14 200 Euros. includes lunch, and materials Sanctuary Basics September 22 September 24 275 Euros. includes lunch, and class materials “那么哪个最好呢?”我听到你哭泣。使用 headers/
@scope
的第二种方法花费的时间更少,也更容易创作,正如你在清单 7-4 中看到的。对于屏幕阅读器的用户来说,这两个例子的最终结果几乎是一样的,只有一个例外。旧的屏幕阅读器不太支持@scope
属性,所以我认为 header/ID 组合方法更健壮,向后兼容性更好。更复杂的表格
下面是上表的一个更高级版本的示例,使用 headers/
@scope
方法以及更新的 HTML5 语法进行编码。其想法是显示介绍性和高级课程的信息,每个课程的名称被编码为标题,跨越几列。从视觉上看,该表类似于图 7-4 中所示的表。
图 7-4 。使用 HTML5 语法和 headers/@scope 方法的更高级的表格
使用 HTML5 语法构建它的代码如清单 7-5 所示。
清单 7-5 。使用 Headers/@scope 方法创建一个更高级的表
`
Animal Sanctuary workshops
`An overview of upcoming Animal Sanctuary workshops in 2012 Course Number Course Start Date End Date Cost Included Extras How do you start an Animal Sanctuary #001 Introduction June 10 June 16 250 Euros includes lunches, and one dinner. #002 Advanced August 10 August 16 550 Euros includes lunches, one dinner and extensive materials. Working with Dogs: A beginners workshop #003 Introduction April 12 April 16 100 Euros includes lunches, and materials. #004 Advanced May 16 May 20 300 Euros includes lunches, and materials. Massage for You & Your Animals #005 Introduction September 29 October 4 200 Euros. A Half-day session is 110 Euros. includes lunch. #006 Advanced November 29 December 4 400 Euros. A Half-day session is 220 Euros. includes lunch. Yoga with Animals #007 Introduction May 18 May 21 100 Euros. includes lunch. #008 Advanced June 18 June 21 200 Euros. includes lunch, dinner and book. A Creative Artistic workshop and Retreat #009 Introduction June 18 June 23 250 Euros includes lunch. #010 Advanced June 18 June 23 500 Euros includes lunch, dinner and art supplies. Why Compassion for Animals matter: Philosophy and Animals #011 Introduction July 12 July 14 200 Euros. includes lunch. #012 Advanced August 12 August 14 400 Euros. includes lunch, and materials. Sanctuary Basics #013 Introduction September 22 September 24 275 Euros. includes lunch. #014 Advanced September 22 September 24 275 Euros. includes lunch, and class materials 您还可以使用 Webaim 的 WAVE 工具栏(我们将在第十章中深入探讨)这样的工具来查看表格本身的标题,既可以查看数据表顶部的标题,也可以查看包含在数据表更深处的标题。图 7-5 显示了波形工具栏界面的概述。
图 7-5 。数据表中第<个>元素的视图
更复杂的表格呢?最终,对于更复杂的表格——例如,单元格跨越多行,并且标题嵌套在表格的更深处——您可以应用的真正起作用的标记会受到一些限制(从可访问性的角度来看)。我强烈建议尽可能地简化你的数据表设计,并确保你使用更可靠的方法,比如标题/ID 组合。向表中添加一个
<caption>
元素是一个很大的帮助,尽管目前在 HTML5 中不赞成使用@summary
,但添加一个元素仍然适用于许多 AT。如果那是一座太远的桥,你可以添加aria-describedby
来提供更多的说明;然而,使用这种方法意味着指令需要是页面上的描述。我会违反法律,仍然添加@summary
来向盲人用户描述复杂的表格(它在视觉上是隐藏的)。话说回来,我觉得我只是对权威有意见。应该构建复杂的表吗?当然,你可以为跨越多列或多行的数据单元格设置标题,但是你真的需要确保在更复杂的表格中嵌入标题(见图 7-5 )并使用适当的 id 在这些标题和数据单元格之间创建编程关联。
尽管随着技术的进步,有更高级的 HTML 标记方法承诺更容易创作或只是“更好”,但在实践中,这里概述的简单方法是您应该坚持的。对于更复杂的表——使用@scope 是最理想的——记住它仍然没有得到很好的支持。因此,即使一个标记方法可能是“好的”(从纯编码的角度来看),并且在语义上有意义,你仍然必须小心,并且测试,测试,测试。困难在于 at 供应商需要赶上作者正在做的事情和规范建议的事情。其实
@scope
里没什么新东西。它已经存在很多年了。注意关于新的 HTML5 表格语法,我必须承认最初我对它有着复杂的感情。然而,当我编写前面的例子时,我发现更简洁的语法首先更容易编写,然后当我检查代码时也很好。我喜欢它在网格中思考的方式。您可以在您选择的编辑器中布置代码,就像您可视化地布置数据表中的表格单元格一样。当然,您也可以用 HTML 4 做到这一点,但是新的语法要简单得多,并且使得可视化解析代码变得更加容易。虽然一开始不太情愿,但发现自己惊喜万分。
使用范围和 AT 支持
虽然从技术上来说,scope 属性应该被今天的一些屏幕阅读器支持,但实际上它真的相当有限。另一方面,对头/ID 组合的支持(如前所述)非常好。AT 供应商可能声称支持
@scope
,但是当您使用它构建数据表时,您可能会注意到使用@scope
的表和不使用@scope
的表之间的差别非常小(如果有的话)。随着时间的推移,出于几个原因,这种情况需要改变。首先,用 header/
@scope
创作可访问的数据表对开发人员来说耗时更少;第二,新的 HTML5 代码更加精简,这意味着更快的页面加载速度等等。此外,@scope
的使用让您有可能标记更复杂的数据表。注几年前,HTML5 工作组采取的立场是数据表不需要标题,而
@scope
足以构建数据表。数据表的标题将从规范中删除。值得庆幸的是,这种情况没有发生,因为这一举动对于 AT 的老用户(有很多)来说是灾难性的。如果你对争论的细节感兴趣,可以查看 HTML5 工作组 ESW 维基: 2描述 HTML5 表格的新方法
规范中提出了一些描述表格的新方法,为了完整起见,我在这里提供了一些例子。如果你愿意,你可以使用它们。然而,我对其中一些有异议,目前对新元素如
<figcaption>
和<details>
的支持很差。随着时间的推移,这种情况将会改变。您需要进行一次调用,以决定是在它之前还是之后提供表的文本描述,然后在它们之间创建一些编程链接。这种模型的论点是,它有助于有认知障碍的人更好地理解表格,这肯定有一定的道理。然而,对于简单的表格来说,这通常是不必要的,更复杂的表格从@summary
描述(不幸的是在 HTML5 中是无效的)或类似的描述中获益更多。规范建议描述数据表的一些方法,可能简单,也可能更复杂,如下所示。
方法 1:以散文的形式,围着桌子
清单 7-6 中的例子使用了表格上方的
<p>
元素作为后面的详细文本描述。这个想法是,描述将满足所有用户的需求,因为它是在浏览器中呈现的。清单 7-6 。数据表的详细文本描述
`
In the next table the number of animals we have in care are given in the first column, Number in Care, the animal type is in the second column, Animal Type, and the third column shows the number that are available currently.
`The number of animals in care that we have and that are available for immediate re- housing. Total in Care Animal Type Number available 12 Older Dog 7 9 Aging Cat 6 14 Young Puppy 9 23 Kitten 15 5 Pony 4 3 Horse 1
2
注意 清单 7-6 有两个标题,因为标记用于引用表格顶部的标题和内嵌的标题。HTML5 规范允许以这种方式引用多个头。
虽然在表的正上方有一个详细的描述是一个好主意(如果需要,屏幕阅读器的用户将能够更容易地发现它,因为它非常接近表),但它仍然有缺陷。这是因为在代码中没有显式的编程关联。正如您现在所知道的,屏幕阅读器用户可以使用他们的 AT 浏览 web 内容,所以显式关联非常有帮助,因为一旦表获得焦点,它就会被宣布。清单 7-6 中的会发生这种情况。
方法 2:对数据表使用 aria-describedby
以前解决这个问题的方法是添加一个描述表格的
@summary
元素。它对视力正常的用户是隐藏的,但对屏幕阅读器用户非常有用。如何提供一个更明确的以编程方式关联的描述?您可以使用一个@summary
,但是您会从验证器(可从[
validator.w3.org](http://validator.w3.org)
获得)得到一个错误。如果你能接受,那很好。另一种方法是使用aria-describedby
指向页面上的描述。代码如清单 7-7 所示。清单 7-7 。使用 aria-describedby 描述表格
`
In the next table the number of animals we have in care are given in the first column, Number in Care, the animal type is in the second column, Animal Type, and the third column shows the number that are available currently.
[…]`The number of animals in care that we have and that are available for immediate re- housing. Total in Care Animal Type Number available 12 Older Dog 7 9 Aging Cat 6 对您的表进行这样的编码可以让屏幕阅读器指向页面上的描述。请注意,它不一定要在表格的正上方或正下方才能工作,只要描述在与表格相同的页面上的任何地方都可以工作。
方法#3:在表格的
HTML5 规范建议您可以在
<caption>
元素中提供这些描述。这类似于清单 7-8 中的代码。清单 7-8 。<中描述表格的标题>
`
Table outlining the number of animals we have in care are given in the first column, Number in Care, the animal type is in the second column, Animal Type, and the third column shows the number that are available currently. Total in Care Animal Type Number available 12 Older Dog 7 […]`
虽然清单 7-8 中的例子是有效的 HTML5,但我觉得它用太多的信息使
<caption>
超载,并且把任何标题的目的从一个简短的描述变成一个更长的描述。用更长的描述来呈现这样的信息可能会用aria-describedby
更好地标记,或者用@summary
更好。方法 4:在表格的标题中,在一个元素中
HTML5 规范还推荐将表格的
<caption>
与新的<details>
元素结合使用,以提供如清单 7-9 所示的描述。清单 7-9 。使用<细节>元素描述表格
`
The number of animals in care that we have and that are available for immediate re- housing. Help the number of animals we have in care are given in the first column, Number in Care, the animal type is in the second column, Animal Type, and the third column shows the number that are available currently.
Total in Care Animal Type Number available 12 Older Dog 7 […]`
在清单 7-9 的例子中,注意两个新元素:
<summary>
和<details>
。新的
<details>
元素表示一个 disclosure 小部件,用户可以从中获得额外的信息或控件。例如,您可以使用它来创建手风琴风格的显示/隐藏控件。请注意,它不适用于脚注。新版本的 Firefox、IE9 和 Safari 5 目前支持这个新元素。同样,默认情况下,这些描述在浏览器中是可见的,但是如果需要,可以使用 CSS 隐藏它们。<summary>
元素是<details>
元素的子元素,用于表示摘要或图例。它不同于 HTML5 早期版本中表格元素的@summary
。方法#5:在同一张图中,在表的旁边
下一个方法,如清单 7-10 中的所示,将整个表格包装在一个
<figure>
元素中,并使用<figcaption>
提供最初的简短描述,使用<p>
元素提供更长的描述。清单 7-10 。用<图符>描述表格
`
The number of animals in care that we have and that are available for immediate re-housing. the number of animals we have in care are given in the first column, Number in Care, the animal type is in the second column, Animal Type, and the third column shows the number that are available currently.
[…]
`Total in Care Animal Type Number available 12 Older Dog 7 这种方法目前的问题是,除了将整个
<table>
包装在一个<figure>
中(at 目前不太支持这种方法),在描述性文本和表格元素之间没有其他编程关联。因此,在对<figure>
元素的支持得到改善之前,使用这种方法是不明智的。在我写这篇文章的时候,Firefox 对<figure>
和<figcaption>
还有一些支持。结论
从前面的例子中可以看出,有很多方法可以使用 HTML5 来描述数据表,并使它们更易于访问。越久经考验和信任的方法通常是最好的,首字母缩写 KISS(保持简单,愚蠢)中的古老格言当然适用。在下一章中,我们将看看 HTML5 表单和一些新元素和表单控件,你可以用它们来使你的表单更具响应性、可用性和可访问性。*