如何利用WCAG 2.2标准打造更加易于访问的网站
一个网站可能看起来很专业,使用鼠标操作时也能运行得非常顺畅,但对某些用户来说,使用它仍然会遇到困难。 有时,某个表单会仅通过颜色来提示用户出现了问题;固定的页眉可能会完全覆盖当前处于键盘焦点位置的元素;登录表单可能会阻止用户从密码管理工具中复制密码并粘贴到表单中;而某个自定义按钮,用鼠标点击时可以正常使用,但当人们使用键盘操作时却毫无反应。 这些其实都是开发过程中做出的决策,并非只有在进行无障碍性审核时才会出现的问题。 《Web内容无障碍性指南》为识别和消除这些障碍提供了统一的标准。WCAG 2.2是最新的WCAG 2建议标准,世界万维网联盟也建议开发人员和各类组织在可能的情况下使用WCAG
一个网站可能看起来很专业,使用鼠标操作时也能运行得非常顺畅,但对某些用户来说,使用它仍然会遇到困难。
有时,某个表单会仅通过颜色来提示用户出现了问题;固定的页眉可能会完全覆盖当前处于键盘焦点位置的元素;登录表单可能会阻止用户从密码管理工具中复制密码并粘贴到表单中;而某个自定义按钮,用鼠标点击时可以正常使用,但当人们使用键盘操作时却毫无反应。
这些其实都是开发过程中做出的决策,并非只有在进行无障碍性审核时才会出现的问题。
《Web内容无障碍性指南》为识别和消除这些障碍提供了统一的标准。WCAG 2.2是最新的WCAG 2建议标准,世界万维网联盟也建议开发人员和各类组织在可能的情况下使用WCAG 2.2。
本文重点探讨了WCAG 2.2中A级和AA级要求,这些要求往往会对前端开发产生直接影响。文章旨在说明无障碍性要求是如何与前端开发决策相互关联的。
目录
什么是WCAG 2.2?
WCAG代表网页内容无障碍指南。W3C制定了这一标准,旨在说明如何让残障人士能够更便捷地访问网页内容。
WCAG 2.2将其各项要求分为原则、指导方针和可测试的成功标准。这些成功标准与具体的技术实现无关,这一点非常重要,因为WCAG并不是专门为HTML、React、WordPress或任何其他技术而制定的。
请看以下这种层次结构:
原则:可操作性
指导方针2.1:支持键盘操作
成功标准2.1.1:键盘可用性
原则为人们提供了总体上的无障碍目标,指导方针进一步明确了这一目标的具体内容,而成功标准则提供了可供测试的具体要求。
W3C还发布了其他资源,例如了解WCAG 2.2、如何满足WCAG 2.2的要求以及WCAG 2.2的实施技巧。这些资源对成功标准进行了说明,并提供了实现方法、示例以及常见的错误案例。它们属于参考性资料,并不属于WCAG的强制性要求。
W3C提供的某项实施技巧可以展示一种满足特定成功标准的方法,但WCAG通常并不要求必须使用这种具体的技术手段;只要能够满足相应的成功标准,其他实现方式也同样有效。
WCAG合规性的判定机制
WCAG定义了三个合规性等级:A级、AA级和AAA级。
这些等级是层层递进的。一个网页如果只满足了AA级的标准,是无法宣称自己达到AA级合规性的;它必须同时满足所有A级和AA级的成功标准。AAA级同样涵盖了A级、AA级和AAA级的各项要求。
这种区分非常重要,因为有时人们在讨论无障碍问题时,会将WCAG简化为一系列单独的检查项目。
你可能会修复菜单中的键盘操作功能、为图片添加替代文本、解决对比度问题等等,这些确实都是有益的无障碍改进措施,但它们并不能自动使整个网站达到“WCAG AA级合规”标准。
WCAG合规性是针对整个网页而言的。如果某个流程需要多个页面来完成,比如结账流程,那么该流程中的所有页面都必须符合所宣称的合规等级要求。
因此,本文中的示例只是展示了如何满足某些特定的无障碍要求,并不能代表整个应用程序达到了WCAG合规标准。
WCAG的四项原则是如何发挥作用的
WCAG将其指导方针归纳为四个原则,人们通常用缩写POUR来记忆这些原则:可感知性、可操作性、可理解性和稳健性。
可感知性意味着用户必须能够理解您所提供的信息。文本说明、字幕、适当的对比度以及可调整的布局设计,都属于这一原则的范畴。可操作性指的是人们如何与界面进行交互。键盘操作、焦点行为、导航功能、指针交互以及响应时间等方面都属于这一范畴。
易理解性关注的是用户是否能够理解界面显示的信息及其运行方式。格式化的提示信息、有用的错误提示、可预测的界面设计以及便捷的身份验证机制都是实现这一目标的关键因素。
稳定性则涉及浏览器及辅助技术是否能够正确解析页面内容。语义化HTML、可访问的标签名称、角色属性、值以及状态等信息,对于确保界面的稳定性至关重要。
虽然这些分类很有用,但实际在处理无障碍设计问题时,HTML、CSS和JavaScript这三者之间的界限往往并不存在严格的划分。例如,一个自定义的下拉列表可能需要在标记中添加语义化信息,在CSS中设置可见的焦点样式,并通过JavaScript来实现正确的键盘交互功能。
因此,将无障碍设计融入到开发流程之中,而不是将其作为开发后期单独进行的任务,才能取得最佳效果。
如何开始使用语义化HTML
在开始编写任何与ARIA相关的代码之前,选择正确的HTML元素是实现无障碍设计的最重要的步骤之一。
<div onclick="submitForm()">>提交按钮</div>
对于鼠标用户来说,他们或许可以点击这个元素,但普通的div标签并不会自动表现出按钮的功能。
<button type="submit">>提交按钮<>/button>
而原生的button标签能够向浏览器明确说明自身的功能,并提供预期的键盘交互行为。
这一点与W3C的成功标准4.1.2:名称、角色、值有关,该标准要求用户界面组件能够以编程方式暴露自身的名称和功能等信息。W3C指出,当开发者按照规范使用这些标准控件时,它们本身就已经提供了大部分所需的信息。
实际应用中,一个简单的原则就是:除非确实有必要,否则不要重新设计浏览器原有的交互行为。
语义化HTML如何呈现页面结构
语义化HTML还能帮助清晰地表达页面各部分之间的关系。
<div class="top">
...
</div>
<div class="navigation">
...
</div>>
<div class="content">
<div class="title">>账户设置</div>>
...
</div>
虽然这些类可以用来创建所需的视觉布局,但它们并不一定能以编程方式准确反映页面的实际结构。
<>header>
...
<>/header>
<>nav aria-label="主导航">
...
<>/nav>>
<main id="main-content">>
账户设置
...
</main>
这种写法才能更清晰地表达页面的结构关系。
成功标准1.3.1:信息与关联关系要求,那些通过视觉方式呈现的结构与关联关系,也应当能够通过编程方式获取,或者以文本形式提供。使用语义标记技术就可以实现这一目标,而无需开发者额外添加辅助功能属性来重新构建这些信息。
这并不意味着使用、和等标签就能自动使页面具备可访问性。其实这意味着你在向浏览器提供更准确的信息,让浏览器能够理解页面内容的具体含义。
如何添加跳过链接
如果页面中的导航结构过于繁琐,使用键盘浏览的用户每次想要进入主要内容之前,都可能需要依次点击所有的导航链接。
<a class="skip-link" href="#main-content">
跳转到主要内容
</a>
<header>
...
<>/header>>
<nav aria-label="主要导航栏">
...
<>/nav>>
<main id="main-content">>
...
<>/main>
你可以将这个跳过链接放在页面的正常显示区域之外,直到用户用键盘选中它时,该链接才会被显示出来:
.skip-link {
position: absolute;
top: -4rem;
left: 1rem;
}
.skip-link:focus {
top: 1rem;
}
这是一种被广泛认可的方法,用于满足成功标准2.4.1:绕过重复内容区块的要求。WCAG关注的是最终效果,而非具体的CSS实现方式。
一个重要的原则是:在自行添加自定义语义标记之前,应先利用HTML本身已提供的语义功能。
如何为图片编写有用的文字描述
为图片添加alt属性是提高页面可访问性的常用方法,但这一规则往往被简化理解了。
成功标准1.1.1:非文本内容要求,非文本内容必须配有能起到相同作用的文化描述文字,不过也有一些例外情况。例如,装饰性内容就可以被设计得让辅助技术忽略它。
关键在于“作用”这一要素。
<>img src="revenue-chart.png" alt="图表"
如果图片的主要用途是展示收入变化情况,那么它的文字描述就应该这样写:
<>img
src="revenue-chart.png"
alt="2024年的收入为120万英镑,2025年增加到了180万英镑。"
>
这并不意味着所有的图表都可以用一句话来概括。
如果某个图表包含多个数据系列或读者需要的详细信息,那么可能还需要附加说明、可供查阅的表格,或是其他方式来传达这些核心内容。
所选择的替代表达方式应当能够反映该图表在其所在上下文中所起的作用。
如何处理装饰性图像
装饰性图像的作用与普通图表不同。
以一个用于分隔内容的视觉元素为例:
<img src="decorative-line.svg" alt="">
此处将`alt`属性设置为空,说明该图像并不包含需要特别说明的信息。
因此,“缺少`alt`属性”与“将`alt`设置为空”这两个情况是不能互换的——这种设计是经过刻意考虑的。
如何处理控件内的图标
现在来看一个包含放大镜图标的搜索按钮:
<button type="submit" aria-label="搜索">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="M10 4a6 6 0 1 0 0 12a6 6 0 0 0 0-12Z"></path>
<path d="m14.5 14.5 5 5"></path>
</svg>
</button>
这个按钮的可用名称是“搜索”,而图标本身并不会重复提供任何信息。
在决定使用何种替代方式来表达图表内容时,不要问“这个图像看起来表示什么?”,而应该问:“如果用户无法看到这个图像,他们会失去哪些信息或功能?”这种思考方式在实现无障碍设计时非常重要。
如何处理颜色、对比度、文本大小调整及布局流动
无障碍设计也会影响到常规的CSS样式设置。
某个布局在您常用的屏幕分辨率下可能看起来很正常,但当其他人改变内容的显示方式时,这个布局可能会变得难以使用。
如何避免过度依赖颜色
想象一下,如果验证失败时输入框的边框会从灰色变为红色,这样的设计会怎么样:
.input {
border: 1px solid #777;
}
.input.error {
border-color: red;
}
颜色确实可以用来提示某些变化,但用户必须能够察觉到这种颜色变化才能理解当前的状态。
成功标准1.4.1:颜色的使用要求颜色不能成为传达信息、指示操作、引发响应或区分视觉元素的唯一手段。
一个更完善的实现方式应该是将样式描述与实际文本结合起来使用。
<label for="email">>电子邮件地址</label>
<input
id="email"
name="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
<p id="email-error">>
请输入格式为name@example.com的电子邮件地址。
<./p>>
你仍然可以使用红色边框,只是它不应该单独用来提示错误信息。
如何检查文本对比度
成功标准1.4.3:对比度(最低要求)规定,普通文本的对比度比率必须至少为4.5:1;而用于表示大量信息的大型文本,其对比度比率的最低要求为3:1,不过这一标准也有一些例外情况。
不要仅通过观察颜色来判断对比度是否合格。两种颜色在你的显示器上看起来可能差异明显,但实际上它们的对比度比率仍可能低于规定标准。因此,在设计和开发过程中,应使用专门的对比度测试工具来进行检测。
非文本元素的对比度与文本元素的对比度有何不同
成功标准1.4.11:非文本元素的对比度涉及那些用于识别界面组件、状态以及有意义的图形元素所需的视觉信息。对于这些非文本元素,其与相邻元素的对比度比率通常也应达到3:1,不过这一标准也有一些适用范围和例外情况。
这涉及到诸如自定义表单控件、有意义的图标、组件的边界显示、被选中的状态以及各种图形信息等内容。因此,即使文本元素的对比度符合要求,也不意味着整个界面的对比度都足够良好。
如何实现文本大小的动态调整
成功标准1.4.4:文本大小的调整规定,除非有特别的规定,否则文本应该能够被调整为最大200%的大小,而且调整后内容或功能不得丢失。
固定尺寸的元素往往会导致这种问题出现。
可以参考以下示例:
.card {
height: 180px;
overflow: hidden;
}
如果文本的长度超出了开发者预期的范围,那么部分内容就会显示不出来。
在那些设计上并不需要固定高度的情况下,允许元素的大小动态调整会更加安全:
.card {
min-height: 180px;
}
不过,这并不能证明该组件完全符合这一标准。你仍然需要实际调整文本的大小并检查结果。
这种CSS设置只是消除了导致失败的一个常见原因而已。
如何进行可重排布局的设计
成功标准1.4.10:可重排布局要求,即使内容的显示尺寸较窄,也不应导致信息丢失、功能失效,同时也不应该需要使用禁止使用的二维滚动方式来查看内容。
对于需要垂直滚动的内容,该标准规定其宽度应相当于320个CSS像素。某些内容,比如地图和数据表格,确实需要采用二维布局,因此属于这一标准的例外情况。
灵活的布局能够帮助普通内容适应不同的显示环境:
.settings-grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
gap: 1rem;
}
当可用空间减少时,相关元素会自动移动到新的行上,而不会导致整个页面的宽度不变。
响应式设计在这里确实能起到帮助作用,但“响应式”与“无障碍访问”并不是同义词。
一个响应式页面仍然有可能隐藏控制按钮、截断文本内容、使部分元素重叠,或者在高放大倍数下失去某些功能。因此,必须实际测试这些行为,而不能仅仅假设媒体查询就能满足无障碍访问的要求。
如何让界面适合键盘使用
最简单的手动无障碍访问测试方法就是不使用鼠标,而仅通过键盘来操作该应用程序。
成功标准2.1.1:键盘使用要求所有功能都必须能够通过键盘界面进行操作;除非某些功能的实现确实依赖于用户的移动路径。WCAG并不禁止界面同时支持鼠标、触摸、语音或其他输入方式。
让我们再回到我们之前讨论的那个自定义控件:
<div onclick="saveSettings()">>保存</div>
仅仅将div元素的外观设置为按钮样式,并不能使其具备按钮的功能。
你可以自己重新实现这种功能:
<div
role="button"
tabindex="0"
>
保存
</div>
不过此时,你的JavaScript代码也必须负责提供相应的键盘交互逻辑。
但在大多数情况下,这是没有必要的:
<button type="button">
保存
<>/button>
原生控件已经实现了大部分所需的交互功能,因此你无需再额外编写代码来模拟这些行为。
W3C的ARIA编写指南明确指出了这一点:ARIA角色并不会让浏览器自动添加与原生HTML控件相同的键盘交互功能。如果你创建了自定义的ARIA组件,那么实现这些交互逻辑就是你的责任。
如何检查是否存在键盘使用障碍
成功标准2.1.2:不存在键盘使用障碍旨在解决这样一种情况:用户通过键盘将焦点定位到某个组件上,但却无法再通过键盘离开该组件。
这一标准对于自定义编辑器、对话框、嵌入式组件以及其他复杂的控件来说尤为重要。
进行键盘测试时,不能仅仅检查是否能够按Tab键直到某个元素获得焦点,还需要进一步验证其他键盘操作是否能正常发挥作用。
<尝试完成实际任务。如果你打开了某个对话框,能否使用其中的控件并关闭它?如果你添加了一个自定义部件,能否正常离开该界面?如果出现了菜单,能否按照预期的键盘操作方式来使用它?>键盘可访问性涉及整个交互过程,而不仅仅是指某个元素是否出现在标签顺序中。
如何保持键盘焦点可见
当用户无法判断当前哪个元素处于焦点状态时,使用键盘进行导航就会变得非常困难。
因此,以下这种CSS代码存在风险:
*:focus {
outline: none;
}
这种代码去掉了浏览器默认提供的焦点指示效果,却没有提供任何替代方案。
成功标准2.4.3:焦点顺序要求键盘可操作的界面必须提供一种能够使键盘焦点指示可见的模式。
如果默认的焦点指示效果不符合你的设计需求,那么应该使用其他可见的方式来替代它,而不要直接将其删除:
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
这只是一个示例,并不能保证你的设计一定符合WCAG标准。你所选择的焦点指示方式仍然需要能够在组件的周围颜色中保持可见性。
WCAG 2.2如何处理被隐藏的焦点
WCAG 2.2在AA级别增加了成功标准2.4.11:焦点不得被完全隐藏(最低要求)。
当某个用户界面元素获得了键盘焦点时,开发者创建的内容不得将其完全隐藏。AA级别的标准要求,至少部分处于焦点状态的元素必须保持可见。
一个“固定标题”示例可以说明这个问题:
.site-header {
position: sticky;
top: 0;
height: 5rem;
}
“固定标题”本身并不会导致可访问性问题,但如果页面滚动时,处于焦点状态的链接或控件被完全隐藏在那个固定标题后面,就会产生问题。
在涉及滚动定位的情况下,以下CSS代码可以帮助解决这个问题:
html {
scroll-padding-top: 6rem;
}
但请不要认为这就能彻底解决问题。实际上,cookie通知、固定的底部导航栏、聊天窗口、固定的工具栏等其他元素也可能会引发类似的问题。
最重要的原则是:当焦点位置发生变化时,用户仍然能够看到处于焦点状态的元素。
如何设计指针目标与拖动交互功能
键盘支持并不能解决所有的交互障碍。WCAG 2.2为触摸屏、拖放界面以及紧凑型控件等场景提出了额外的要求。
如何提供拖动的替代方案
想象这样一个任务列表:用户只能通过拖动卡片来重新排列它们的顺序。在这种情况下,如果不能为用户提供其他交互方式,就会造成使用不便。
对于许多用户来说,拖动操作可能会非常实用,但这一功能的实现取决于用户是否能够正确地按下鼠标指针、在保持交互状态的同时移动它,然后再将其释放到正确的位置。
成功标准2.5.7 拖动操作要求:那些需要通过拖动来实现的功能,也应当能够通过单次鼠标点击操作来完成——除非拖动操作对于实现该功能来说是必不可少的。
你可以在提供拖放功能的同时,再为用户提供另一种控制方式:
<article class="task">
制作月度报告
具体的重新排序逻辑取决于你的应用程序的设计需求。
关键在于,用户应该有另一种基于鼠标指针的操作方式来完成同样的功能,而无需进行拖动操作。
WCAG并不是在要求“不要使用拖放功能”,而是强调:拖动操作不应不必要地成为实现某些功能的唯一途径。
如何确定目标元素的大小
成功标准2.5.8 目标元素的最小尺寸是WCAG 2.2 AA级规范中的另一项重要规定。
该标准规定目标元素的最小尺寸应为24像素×24像素,或者采用其他规定的间距值;同时也有一些例外情况。因此,不能简单地将这一标准理解为“所有可点击元素的大小都必须至少为24像素×24像素”。
对于那些独立的图标按钮来说,你可以选择为其设置更大的目标区域:
.icon-button {
min-width: 2.75rem;
min-height: 2.75rem;
display: inline-grid;
place-items: center;
}
在典型的字体大小下,这样设置的目标区域尺寸会大于WCAG规定的最小值。
不过,图标的实际显示尺寸仍然可以更小:
<button
class="icon-button"
type="button"
aria-label="删除发票"
>
图标的实际尺寸与可交互目标区域的尺寸并不一定相同。
在设计复杂度较高的界面时,这种区分是非常有用的。
如何确保无障碍名称与可见标签保持一致
成功标准2.5.3 名称中应包含标签文字适用于那些具有可见文本标签的控制元素。
无障碍名称中应当包含这些可见的标签文字。这对于那些通过语音操作界面、并依靠能够看到的文字来识别控制元素的用户来说,尤为重要。
请避免使用以下代码:
<button aria-label="查找产品">
搜索
</button>
可视标签显示为“搜索”,但可访问名称应为“查找产品”。
在这种情况下,最简单的版本才是最佳选择:
<>button>
搜索
<>/button>
如果确实需要额外的可访问性说明,那么可以保留可视标签上的文字内容:
/button>
在添加aria-label属性之前,请先确认可视文本是否已经为该控件提供了足够明确的可访问名称。
如何构建更易于使用的表单
表单涉及多个与可访问性相关的方面:结构、提示信息、错误提示、输入字段的用途以及状态变化等。
首先从输入字段本身开始着手处理。
如何为表单控件添加标签
这种编写方式非常常见:
<>input
type="email"
name="email"
placeholder="电子邮件地址"
>
占位符虽然能提供视觉提示,但它并不能替代合适的标签。
正确的做法应该是这样写:
/label>
成功标准3.3.2:标签或提示信息要求:当内容需要用户输入时,必须提供相应的标签或提示信息。
for属性和属性还能确保标签与输入字段之间存在程序上的关联关系。
如何识别输入字段的常见用途
成功标准1.3.5:识别输入字段的用途规定:对于那些用于收集用户信息的输入字段,其用途必须能够在技术支持的情况下通过程序方式被识别出来。
HTML中的autocomplete属性有助于明确这些输入字段的常见用途:
<>label for="full-name">
全名
<>/label>
/label>>
这样,浏览器和其他辅助工具就能为用户提供有用的输入提示功能。
如何编写有意义的验证错误信息
现在来看一个错误信息的例子:
输入无效。
这样的错误信息几乎无法为用户提供任何有用的信息:到底是哪个输入内容无效?出了什么问题?需要修改哪些地方?
成功标准3.3.1 错误识别要求系统能够自动检测输入错误,从而确定出出现问题的具体内容,并以文本形式对这一错误进行描述。
一种实现方式可能如下所示:
<label for="email">
电子邮件地址
<>/label>
<input
id="email"
name="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
>
<p id="email-error">>
请输入格式为“name@example.com”的电子邮件地址。
<>/p>
aria-invalid="true"这一属性用于提示输入信息无效;aria:description则用于将相应的提示信息与相关字段关联起来。
更重要的是,这些提示信息能让用户清楚地知道需要修改哪些内容。
成功标准3.3.3:错误提示在AA级别中进一步规定了:当系统检测到输入错误并且知道如何纠正这些错误时,应提供适当的提示信息,除非这样做会影响到内容的安全性或使用目的。
我们的目标并不是让所有的错误提示信息都变得冗长,而是要让它们真正具有实用性,能够帮助用户解决问题。
如何避免重复输入信息
以结账流程为例:用户在某个步骤中填写了收货地址,但在下一个步骤中却需要再次输入相同的地址用于账单填写。
WCAG 2.2在A级别中规定了成功标准3.3.7:重复输入信息。当在同一流程中需要用户再次输入之前已经填写过的信息时,这些信息应该能够自动填充或供用户选择;不过也有例外情况,例如重新输入信息是出于安全考虑,或者之前的信息已经不再有效。
因此,结账页面可以提供如下选项:
<label>
使用我的收货地址作为账单地址
<>/label>
需要注意的是,这一规定仅适用于同一流程中的信息重复情况,并不意味着每个网站都必须记住用户之前输入的所有信息。
这个标准也说明了为什么无障碍设计并不仅仅局限于屏幕阅读器的支持功能。
减少不必要的重复操作可以降低完成任务所需的认知负担和交互难度。
如何保持帮助提示的一致性
WCAG 2.2还在A级别中规定了成功标准3.2.6:帮助提示的一致性。如果某些帮助提示在多个页面上反复出现,那么它们的显示顺序应该保持一致,除非用户主动要求进行更改。这些帮助提示可以包括人工联系信息、联系方式、自助帮助选项以及自动联系机制等。
假设你的所有账户页面都在页眉中提供了支持链接:
<header>
Acme
支持中心
请不要在彼此相关的页面之间随意移动这些辅助功能机制。
一个关键的要点是,WCAG 2.2并不要求每个网站都必须使用这些辅助机制中的某一种。
只有当某些辅助功能已经存在,并且在同一组页面中被反复使用时,这一规定才适用。
因此,从开发的角度来看,这一规定的主要意义在于确保一致性。
如果用户已经知道了某个辅助功能在哪个页面上可以找到,就应避免让他们在另一个页面上再次去寻找它。
WCAG 2.2对认证机制的影响
认证也是WCAG 2.2中发生变化的一个方面。
以一个故意禁止用户使用复制粘贴功能的登录表单为例:
passwordInput.addEventListener("paste", (event) => {
event.preventDefault();
});
这种设计看似是在鼓励用户手动输入密码,但实际上它可能会干扰那些有助于减少用户记忆或输入密码负担的辅助功能。
成功标准3.3.8:可访问的认证机制(最低要求)规定了那些需要用户进行认知能力测试的认证流程。
对于AA级标准来说,只要存在其他可行的替代方案或辅助功能,这种测试就是允许的。W3C明确指出,密码管理工具和复制粘贴功能都可以帮助减轻用户在认证过程中的认知负担。
一个常规的登录表单是可以支持这些辅助功能的:
<label for="username">
电子邮件地址
<>/label>
<input
id="username"
name="username"
type="email"
autocomplete="username"
>
<label for="password">
密码
<>/label>
<input
id="password"
name="password"
type="password"
autocomplete="current-password"
>
将这一标准简化为“WCAG 2.2禁止使用密码”是不准确的——事实上,该标准并没有这样的规定。
输入密码本身确实需要用户进行认知能力测试,但只要用户有辅助工具来帮助完成这个过程,比如密码管理工具能够自动填充密码字段,那么这种测试就是被允许的。
同样的道理也适用于多因素认证机制。
如果某个认证流程要求用户在一台设备上查看验证码,然后手动在另一台设备上输入它,那么就需要考虑是否可以为用户提供一条能够避免这种认知负担的路径。W3C的指导文件中明确提到了那些包含多个步骤的认证流程,以及为这些流程提供可访问路径的必要性。
这个例子充分说明了为什么具体的技术标准比简化的无障碍性检查清单更为重要。
如何在不替换HTML代码的情况下使用ARIA
ARIA的全称是可访问的富互联网应用。
它提供了一些角色、状态和属性,这些元素能够帮助网页应用程序传递那些辅助技术可能无法获取的信息。ARIA确实很有用,但同时也很容易被误用。
举个例子来看:
<div role="button">
下单
</div>
`role`属性告诉辅助技术接口,该元素代表一个按钮,但它并不会使这个元素真正表现出按钮的行为。
W3C的ARIA编写实践指南将ARIA的角色描述为一种“承诺”:当你使用`role="button"`时,你就需要自己负责提供预期的键盘操作和交互行为——ARIA本身并不会自动让浏览器添加这些功能。
如果已经有对应的原生HTML元素存在,那么应该优先使用这些元素:
<button type="button">
下单
</button>
ARIA如何传递组件的状态信息
当仅使用HTML无法充分表达组件的当前状态时,ARIA就显得非常有用了。
以一个可切换显示/隐藏的选项为例:
<button
id="account-options-trigger"
type="button"
aria-expanded="false"
aria-controls="account-options"
>
账户设置
</button>
<div id="account-options" hidden>
个人资料
安全设置
<>/div>
你可以让`aria-expanded`属性与元素的实际显示状态保持同步:
const trigger = document.querySelector(
"#account-options-trigger"
);
const panel = document.querySelector(
"#account-options"
);
trigger.addEventListener("click", () => {
const isExpanded =
trigger.getAttribute("aria-expanded") === "true";
trigger.setAttribute(
"aria-expanded",
String(!isExpanded)
);
panel.hidden = isExpanded;
});
这段JavaScript代码做了两件事:首先它会改变面板的显示状态,其次它会更新与这个按钮相关的辅助技术状态信息。
如果面板在视觉上已经显示出来了,但`aria-expanded`属性的值仍然是`false`,那么用户界面就会同时呈现两种相互矛盾的状态信息。
这正好说明了一个重要的ARIA规则:ARIA状态描述的内容必须与实际存在的界面相匹配。
对于对话框、下拉列表、标签页、菜单和网格等更复杂的界面元素,W3C的ARIA编写实践指南提供了详细的交互模式和示例。同时,W3C也明确指出,这份指南属于实现指导性质,并非强制性的无障碍标准。
如何让动态状态信息易于被访问
现代用户界面经常会在不重新加载页面的情况下更新内容。
例如,当用户保存个人资料后,可能会看到这样的提示:
您的设置已保存。
或者在进行搜索之后,也会出现类似的反馈信息。
找到了18条结果。
有视力的用户通常可以在不离开当前控制元素的情况下注意到这些更新。
辅助技术也需要一种编程方式来识别相关的状态信息。
成功标准4.1.3 状态信息要求相关状态信息必须能够通过编程方式来确定,这样辅助技术才能在无需将焦点放在这些信息上时将其呈现出来。
对于常规的保存确认操作,可以使用role="status"属性:
<button id="save-settings" type="button">
保存设置
</button>
<p id="save-status" role="status"></p>
然后更新其内容:
const saveButton = document.querySelector(
"#save-settings"
);
const saveStatus = document.querySelector(
"#save-status"
);
saveButton.addEventListener("click", () => {
saveStatus.textContent =
"您的设置已保存。";
});
浏览器可以在不将键盘焦点从“保存”按钮上移开的情况下,将这些状态变化告知相应的辅助技术。
并非所有的动态DOM变化都属于状态信息。
WCAG对这一概念的定义更为狭义:它包括与操作的结果或成功情况、应用程序的等待状态、进程的进展程度,或是错误的存在有关的信息——不过,这些更新本身并不一定会导致上下文的改变。
不要把每一个会发生变化的内容都视为需要实时显示的信息。过于频繁地弹出提示信息反而会引发其他的可用性问题。
只应将那些用户在继续当前任务时确实需要了解的信息,用状态语义来呈现。
如何测试网站的无障碍访问功能
无障碍访问功能的测试最好结合多种方法来进行。
WCAG本身就旨在支持通过自动化工具和人工评估两种方式进行测试。自动化扫描工具可以发现许多技术性问题,但它无法可靠地判断所有的无障碍访问要求是否得到满足,也无法确定整个使用流程是否合理。
如何开始使用自动化测试
自动化工具适用于那些需要重复进行的技术性检查。
它们能够发现许多与可访问名称、对比度问题、无效的ARIA属性使用、表单元素之间的关系等因素相关的问题。
然而,当正确性的判断依赖于具体含义时,自动化测试就会遇到局限性。
工具可以告诉你某张图片是否具有alt属性,但它无法始终确定这些文字是否能准确表达这张图片的含义。
因此,自动化测试应该只是评估过程的开始,而不是结束。
如何进行键盘测试
打开该页面,将鼠标移开,尝试仅使用键盘来完成实际操作。
首先使用Tab键来浏览交互式元素,而使用Shift + Tab键则可以倒退浏览。
在适当的情况下,可以使用Enter和Space键来激活相应的控件。某些自定义组件也可能根据其交互方式,使用箭头键或Escape键进行操作。ARIA编写规范中的键盘使用指南文档对常见组件的行为进行了规定。
不要只是简单地按几次Tab键就停止测试。
例如,如果你正在测试结账流程:
导航到购物车页面。
修改商品数量。
继续进行结账操作。
逐项填写表格内容。
提交订单。
修正出现的错误。
完成整个流程。
在测试过程中,要确认自己能够访问并操作所有必要的控件,确保不会错过任何组件,遵循合理的焦点切换顺序,了解当前的焦点位置,并避免被其他元素遮挡而无法看到被聚焦的内容。
如果遇到问题,相关的规范要求包括:成功标准2.1.1 键盘使用、成功标准2.1.2 避免键盘使用陷阱、成功标准2.4.3 焦点顺序、成功标准2.4.7 焦点内容可见,以及成功标准2.4.11 避免焦点内容被遮挡。
如何测试缩放、尺寸调整及布局重排功能
你可以在浏览器中直接进行基本的缩放测试。
在大多数浏览器中:
在Windows或Linux系统中使用Ctrl + +
在macOS系统中使用Cmd + +
使用Ctrl/Cmd + 0可恢复到默认缩放比例
W3C的缩放功能简易检测工具建议将缩放比例设置为200%进行测试。
在增加缩放比例后,要仔细检查页面内容,看是否存在以下问题:
文本被截断的情况
元素相互重叠的现象
某些控件消失不见了
导航功能不再正常工作
内容被其他元素遮挡而无法显示
普通页面内容需要水平滚动才能查看完整
你还可以使用较窄的浏览器窗口或响应式浏览工具,来观察内容在不同屏幕尺寸下的布局变化。
这样就可以验证成功标准1.4.4 文本尺寸调整以及成功标准1.4.10 布局重排中规定的行为是否得到满足。
如何测试颜色与对比度
可以使用对比度检测工具,或浏览器开发者工具中提供的颜色信息来测量前景色与背景色的搭配效果。
不仅要对普通文本进行测试,还要对自定义控件边框、图标以及状态指示符等非文本元素进行检查。
之后再单独测试那些依赖于颜色的元素。例如,如果某个错误提示字段会变成红色,可以先忽略这种颜色变化,然后判断是否有其他可见的提示方式仍能传达错误信息。
这些测试内容对应于:成功标准1.4.1 颜色的使用、成功标准1.4.3 对比度(最低要求)以及成功标准1.4.11 非文本元素的对比度。
如何手动测试表单
测试表单时不要只使用有效的数据,应该故意输入错误信息,以便覆盖尽可能多的情况。
可以将必填字段留空,输入格式错误的电子邮件地址,或者提交表单应拒绝接受的值。
然后检查自己是否能够:
识别出存在问题的字段
理解错误提示信息
确定如何纠正这些问题
通过键盘操作找到出现错误的部位
修正错误信息后继续使用表单
同时,还可以利用浏览器开发者工具检查表单控件,确保可见的标签和说明确实与相应的字段关联正确。
这些测试有助于验证:成功标准3.3.1 错误信息的识别、成功标准3.3.2 标签或说明文字以及成功标准3.3.3 错误提示建议。
如何测试指针与拖动交互功能
如果你的界面支持拖放操作,先正常完成一次拖放动作,然后再尝试不使用拖动方式来执行相同的功能。
例如,如果你可以将某个任务拖放到新的位置,那么也要检查其他通过指针操作的控件是否也能实现同样的移动功能。
这种测试方法有助于验证成功标准2.5.7 拖动操作。
对于较小的控件,建议使用浏览器开发者工具来查看实际渲染后的交互区域,而不仅仅依靠可视图标进行判断。
在检查成功标准2.5.8 目标元素的最小尺寸时,尤其要关注关闭按钮、轮播控件、分页项、图标按钮以及布局密集的工具栏。
如何检查无障碍访问树
现代浏览器的开发者工具能够显示与各种元素相关的无障碍访问信息。
请仔细检查那些重要的控件,并将无障碍访问树所显示的信息与界面实际呈现的内容进行对比。
例如,一个按钮在视觉上可能被标记为“搜索”,但其无障碍访问名称却可能完全不同;某个可展开的元素虽然看起来已经打开,但它的`aria-expanded`属性值可能仍然为`false`。
通过检查无障碍访问树,就可以发现这些不一致之处。
如何使用辅助技术进行测试
在使用屏幕阅读器进行测试时,应重点关注用户能否完成整个操作流程。
以填写表格为例:先导航到各个输入字段,确认它们的标签内容,然后输入错误的信息并提交表单,接着找到并理解出现的错误,将其更正,最后确认操作是否成功。
问题不应该是:“屏幕阅读器能读懂这个页面吗?”
用户能否完成整个操作,并理解最终结果是什么?
一个更有意义的问题是:使用有残疾的用户进行测试,可以帮助我们发现那些自动化评估或基于标准的测试可能忽略的可用性障碍。
结论
当将WCAG的相关要求与日常的开发决策结合起来考虑时,这些规范就会变得更容易理解。关键在于:不要再把无障碍访问功能视为最后的验收环节,而应该将其融入到整个界面设计的过程中去。
相关文章
如何使用针对用户的OAuth访问机制来构建人工智能代理程序【完整手册】
当你的AI代理同时为多个人提供服务时,每一次工具调用都必须明确:该代理究竟是在代表哪位用户行事。让我们通过构建一个能够与Slack和GitHub连接的AI代理来学习如何解决这个问题。 当使用Slack时,系统会使用 해당用户的 workspace;而在GitHub上创建问题时,也会以该用户的身份在其有权访问的仓库中操作。虽然代理可能会犯错,但它绝对不能使用错误用户的权限来进行操作。 解决这个问题的方法分为两个部分,而这两个部分都在本教程的前半部分进行了讲解: 每位用户都需要单独授权。 Alice为自己授权Slack,Bob也为自己授权Slack。 代理传递的是标识符,而不是令牌。 像 alic
阅读全文
如何让你的副业项目被人们注意到,并吸引到愿意付费使用的用户
2022年,我在业余时间开发了一个小型微服务产品,最终以几千美元的价格将其卖了出去。如今,有了人工智能工具的帮助,开发这样的产品可能会更加容易。 但真正发生巨大变化的是获取关注的成本,而不是开发软件本身的成本。 我认为,在2026年,产品的分发渠道将比开发本身更为重要。在这篇文章中,我会与大家分享我在产品开发过程中所学到的经验,并试图劝阻大家在开始下一个项目之前,先不要急着直接投入编码工作。 读完这份指南后,你应该能够掌握一些实用的方法和思路,这些方法可以帮助你将自己那些充满热情的项目推向市场。 需要明确的是,这篇文章主要是针对那些正在开发数字产品的人,尤其是软件产品。不过,这些概念同样适用于
阅读全文
如何使用 Shadcn UI 在 React 中构建可扩展的客户身份验证及入职流程
任何具有合规性要求的B2B SaaS产品(比如涉及银行业务、贷款服务、工资发放或加密货币相关的应用)在开发初期都会遇到同样的问题:在允许企业使用你的平台之前,你必须先核实他们的身份。 这意味着需要收集企业的类型信息、审核他们的注册文件,并向用户展示他们的验证进度,但整个流程不能让人感觉像是在填写繁琐的海关表格一样。 本文详细介绍了如何利用Shadcn UI构建一个功能完备的三步客户身份验证流程:包括用于显示操作进度的步骤提示组件、用于选择账户类型的单选组、用于上传文件的区域,以及用于显示验证状态的警告提示。你会看到实际的代码实现,而不仅仅是简化后的示例代码,同时也会了解到每个设计决策背后的理由
阅读全文
Flutter前端系统设计:在人工智能时代,如何像资深工程师一样思考
系统设计长期以来一直被视为后端领域的问题。 如果你问一群Flutter工程师“系统设计到底意味着什么”,他们中的大多数人会提到服务器架构:负载均衡器、数据库以及微服务。 但如果你让他们设计一个分布式缓存系统或画出一个消息队列的示意图,他们会犹豫不决。而当你要求他们为社交Feed应用开发Flutter客户端时,他们就会立刻打开新文件开始编写组件代码。 这种差距确实存在,不过正在迅速缩小。 随着Flutter应用程序变得越来越复杂——它们具备了实时功能、离线支持、多平台兼容性,同时还包含需要维护的人工智能生成代码——在编写任何一个组件之前所做出的架构决策,其重要性已经与后端架构相当了。 在那些以产
阅读全文