特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
近一年来一直以来都在致力让手淘互动项目更有温度,虽然借助自己所掌握的有关于A11Y(Web可访问性)相关的理论知识,让互动项目更具可访问性,但其中有很多细节还是有待于完善,特别是焦点冗余部分,更是令我感到头痛。为了优化这方面的细节,我尝试着通过 WAI-ARIA 中 aria-label
、 aria-labelledby
和 aria-describedby
属性来进行优化,却事与愿违,而且这几个属性一直令我感到困惑。为了彻底的能搞清楚这几个属性,我打算花一些时间来和大家一起探讨它们。如果你对这几个属性感兴趣的话,请继续往下阅读。
先说一下背景
一直以来,在无障碍实施或优化方面都有一个令我感到非常头痛的问题(现象),那就是开启“旁白”朗读的时焦点过于太细化,也就是焦点冗余。比如下图所示:
再把问题细化一下,卡片中的价格“¥109.00”我们在构建HTML的时候分面三个节点:
<div>
<span>¥</span>
<span>109</span>
<span>.00</span>
</div>
千万别问我为什么要这样来构建HTML的DOM结构,这是有一定的需求在这里。也正因为是这个原因,在部分屏幕阅读器中三个<span>
都会有焦点:
屏幕阅读器会将其朗读:“日元符,109, .00”。使用浏览器开发者工具不能发现,它们对应着相应的可访问树:
起初我想着,借用aria-label
、aria-labelledby
和aria-describedby
几个属性,事情应该不会过于复杂,比如:
<!-- aria-label -->
<div aria-label="¥109.00">
<span>¥</span>
<span>109</span>
<span>.00</span>
</div>
<!-- aria-labelledby -->
<div aria-labelledby="a11y__node--1 a11y__node--2 a11y__node--3">
<span id="a11y__node--1">¥</span>
<span id="a11y__node--2">109</span>
<span id="a11y__node--3">.00</span>
</div>
<!-- aria-describedby -->
<div aria-describedby="a11y__node--1 a11y__node--2 a11y__node--3">
<span id="a11y__node--1">¥</span>
<span id="a11y__node--2">109</span>
<span id="a11y__node--3">.00</span>
</div>
最终结果,并没有达到预期所要的结果。
那这是为什么呢?为了找到相应的答案或者搞清楚为什么没有达到预期结果,我重新查阅了 WAI-ARIA相关的文档。从规范中得知,“可访问名称和描述有着映射关系”:
Information concerning name and description accessibility API mappings, including relationships, such as labelled-by/label-for and described-by/description-for, is documented in the Core Accessibility API Mappings specification [CORE-AAM-1.1]. See the mapping table entries for
aria-label
,aria-labelledby
, andaria-describedby
.
大致意思是:核心易访问性API映射规范中记录了关于可访问性名称和描述对应的映射关系,包括关系,比如标签由(labelled-by
)、标签为(label-for
)和描述由(describled-by
)、描述为(description-for
)。比如ARIA中的aria-label
、aria-labelledby
和aria-describedby
等属性。
可访问性的几个重要概念
在详细介绍或探索aria-label
、aria-labelledby
和aria-describedby
之前,有几个重要的概念必须先理清楚:
ARIA标签和关系
先来了解一下ARIA标签属性和关系属性。
ARIA标签属性
在ARIA中提供了多种向元素添加标签和说明的机制。事实上,ARIA是唯一一种可以添加可访问帮助或说明文本的方式。
而aria-label
、aria-labelledby
、aria-describedby
这几个就是ARIA中用于创建可访问标签的属性。
ARIA关系属性
无论页面元素的DOM属性如何,关系属性都会在它们之间创建语义关系。比如aria-labelledby
,关系将是“此元素由另一个元素标记”。
ARIA规范中有八个关系属性,除了我们将要探索的aria-describedby
、aria-labelledby
之外,还有aria-activedescendant
、aria-controls
、aria-flowto
、aria-owns
、aria-posinset
和aria-setsize
。其中除了aria-flowto
和aria-posinset
之外的六个关系属性都是通过引用一个或多个元素的方式在页面元素之间创建一个新链接。各个属性的区别是链接的含义及向用户呈现的方式。
可访问名称和描述
每个平台访问性API都包含一种方法,用于为在可访问性树中创建的每个可访问对象分配和检索可访问名称和可访问描述属性。这些相关属性的实现方式和名称因API的不同而有所不同。
例如,在MSAA中,所有可访问对象都支持accName
属性,该属性存储对象的可访问名称。如果对象还支持具有可访问的描述,则MSAA将此避税性存储在对象的accDescription
属性中。
使用ATK的软件可以读写对象的可访问名称(accessible-name
)和可访问描述(accessible-description
)属性。反过来,AT-SPI可以通过它的atspi_accessible_get_name
和atspi_accessible_get_description
函数查询这些属性的值。
UIA可访问性树中的自动化元素有一个Name
属性。当对象还支持具有可访问的描述时,UIA将此属性存储在对象的FullDescription
属性中。
在AX API中实现可访问名称和可访问描述的方法与其他平台API有些不同。当名称被可视化呈现时,可访问名称使用AXTitle
属性公开,而当对象的名称未被可视化呈现时,使用AXDescription
属性。对象的可访问性描述(如果提供的话)应该始终在AXHelp
属性中公开。
其中ATK与实现者最相关,而AT-SPI与消费者最相关。在映射WAI-ARIA的角色(roles)、状态(states)和属性(properties)的上下文中,用户代理是实现者并使用ATK。ATs技术(屏幕阅读器)是消费者,使用AT-SPI。
其中对MSAA、ATK、AT-SPI、UIA、AX API等专业术语不太了解,不要过于紧张,因为这些在我们接下来的内容关连性不会很紧密。不过对于“可访问名称”和“可访问描述”两个概念需要有一定的了解。
可访问名称
可访问名称(Accessible Name)是用户界面元素的名称。每个平台可访问性API都提供了可访问名称(accessible-name
)属性。可访问名称的值可能来自用户界面元素的可见属性(比如按钮上可见的文本)或不可见属性(如描述图标的可替代文本,即alt
中的值)。
来看一个说明可访问名称属性简单用法的示例,比如有一个“OK”按钮。文本“OK”是可访问名称。当按钮获得焦点时,辅助技术(比如屏幕阅读器)可以将平台的角色描述与可访问名称连接起来。例如,屏幕阅读器可能会朗读“按钮 OK”或“OK 按钮”。角色描述的连接顺序和细节(例如,“按钮”、“按钮”、“可点击的按钮”)由平台可访问性API或辅助技术决定。
可访问描述
可访问描述提供了与接口元素相关的附加信息,补充了可访问名称。可访问性描述可能是可视的,也可能不是。
可访问树(AOM)和 DOM树
可访问性树(AOM)和DOM树是并行结构。粗略地说,可访问性树是DOM树的一个子集。它包括用户代理的用户界面对象和文档的对象。在可访问性树中为应该公开给辅助技术的每个DOM元素创建可访问对象,因为它可能触发可访问性事件,或者因为它有需要公开的属性、关系或特性。一般来说,出于性能或简单性的考虑,如果某些内容可以删除,那么它就会删除。例如,只有 现代战争样式更改而没有语义的<span>
可能无法获得它自己的可访问对象,但是样式更改将通过其他方式公开。
或者说AOM和DOM之间的关系,用下图来描述可能会更易于理解一些:
对于用户界面和辅助技术,也可以用AOM和DOM来描述它们之间的关系:
注意,可访问树AOM在A11Y中是一个非常重要的知识体系,如果要彻底的掌握或更好的构建可访问性Web应用,有必要掌握AOM相关的知识。但在这里将不做过多阐述,如果你对这方面知识感兴趣的话,建议你花时间阅读下面这些教程:
- Accessibility Object Model
- Accessibility Object Model
- Today, I learned about the Accessibility Tree
- Web Components and the Accessibility Object model (AOM)
- The Accessibility Tree
- Playing with the Accessibility Object Model (AOM)
aria-label
、aria-labelledby
和aria-describedby
有了上面的基础我们来看aria-label
、aria-labelledby
和aria-describedby
的具体使用。
aria-label
、aria-labelledby
和aria-describedby
是ARIA的属性,它们主要是给HTML元素添加可访问性名称。
在构建Web页面的时候,并不是所有元素都具备可访问性名称,如果需要为更多不同用户群体访问Web提供平等权利以及更好的体验,就需要借助ARIA相关的特性为其提供可访问性名称和可访问性描述。比如说,在Web上有某种指明元素用途的视觉指示(例如,使用图形而不是文本的按钮),但是仍需要向无法获取视觉指示(例如,仅使用图像指示其用途的按钮)的任何人阐明该用途。
这个时候,我们就需要aria-label
、aria-labelledby
和aria-describedby
等属性为图标按钮提供相应的描述。虽然他们三个都可以给元素提供可访问性名称和描述(或者关联描述),但他们的使用还是有所差异的,而且不同的ATs技术对其呈现方式也会有所差异。在接下来的示例主要以iOS的“VoiceOver”来做测试。
aria-label
我们从最基本的开始。
众所周知,在构建Web应用或Web页面时,很多元素(HTML标签)都会有自己文本内容或者说可描述的内容,比如说:
- 标题
<h1></h1>
会有自己的文本内容 - 图像
<img>
会有可替代文本(alt
) - 交互元素,比如
<input>
会有<label>
相关联
对于有可访问性描述,屏幕阅读器一般情况之下都可以很好的向用户呈现,比如:
<h1>欢迎来到W3cplus!</h1>
当标题<h1>
获得焦点时,“VoiceOver”会朗读:
欢迎来到W3cplus!,标题级别1
如果我们把<h1>
换成无语义的<div>
标签,这个时候“VoiceOver”会朗读:
欢迎来到W3cplus!
使用Chrome浏览器开发者工具查看“Accessibility”选项,可以看到<h1>
和<div>
对应的AOM:
上面两个示例,不管是有语义的标签元素(<h1>
)还是无语义的标签元素(<div>
)都有对应的文本内容,“VoiceOver”都可以将其文本节点朗读出来。接下来,我们来看一个没有文本的示例:
<button>
<svg t="1602668295844" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4611" width="200" height="200">
<path d="M669.781333 130.752c71.637333-11.093333...z" fill="#3D3D3D" p-id="4612"></path>
</svg>
</button>
<div>
<svg t="1602668350662" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4741" width="200" height="200">
<path d="M662.634667 353.749333c33.493333-33.301333 ...z" fill="#3D3D3D" p-id="4742"></path>
</svg>
</div>
当焦点在<button>
元素上时,“VoiceOver”会告诉你:
按钮
可能是,心形
但并不知道是什么“按钮”,对于一些视力有障碍的人群,他们就无法获取到按钮上的信息:
而该示例中的<div>
无法获得焦点,“VoiceOver”不会有任何信息的输出。
针对于这样的场景,我们就可以使用aria-label
属性。
<button aria-label="喜欢">
<svg t="1602668295844" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4611" width="200" height="200">
<path d="M669.781333 130.752c71.637333-11.093333...z" fill="#3D3D3D
如需转载,烦请注明出处:https://www.w3cplus.com/a11y/aria-label-and-aria-labelledby.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!