无障碍简介以及它如何转化为 React UI 组件。
无障碍是 Prime UI 库的主要关注点,PrimeReact 也不例外。PrimeTek 团队已启动一项重要流程,以审查和增强组件的无障碍功能。本指南记录了 PrimeReact 将遵循的通用指南的基础,每个组件的文档都将有一个单独的 无障碍 部分,其中说明键盘支持、屏幕阅读器兼容性、实现细节以及实现 WCAG 合规性的技巧。这项工作已为 PrimeVue 和 PrimeNG 完成,目前正在移植到 PrimeReact 中,以便在 2023 年第四季度完成。
根据世界卫生组织的数据,世界上 15% 的人口在某种程度上患有残疾。因此,任何环境中的无障碍功能(例如轮椅用户的坡道或带有字幕的多媒体)对于确保任何人都可以消费内容至关重要。
残疾类型多种多样,因此您需要充分了解您的受众以及他们如何与创建的内容互动。主要分为四个类别:
失明、低视力或色盲是常见的视觉障碍类型。屏幕放大镜和色盲模式通常是浏览器的内置功能,而对于依赖屏幕阅读器的人来说,页面开发人员需要确保屏幕阅读器可以读取内容。流行的阅读器有 NVDA, JAWS 和 ChromeVox.
耳聋或听力损失是指完全或部分无法听到声音。听力障碍人士使用辅助设备,但与网页互动时可能不够。常见的实现方式是为音频内容提供文字替代方案、文本和字幕。
行动障碍人士由于肢体缺失、瘫痪或其他各种原因导致行动相关残疾。头部指针等辅助技术是一种与屏幕交互的设备,而键盘或触控板仍然是无法使用鼠标的人的解决方案。
认知障碍范围更广,包括有学习障碍、抑郁症和阅读障碍的人。精心设计的内容也会为没有残疾的人带来更好的用户体验,因此为认知障碍进行设计会导致为任何用户带来更好的设计。
应该首选原生表单元素,而不是用于其他目的的元素,例如演示。例如,下面的按钮由浏览器呈现为表单控件,可以通过制表符接收焦点,并且也可以使用空格键来触发。
<button onClick={e => console.log(e)}>Click</button>
另一方面,使用 div 的基于花式 CSS 的按钮没有键盘或屏幕阅读器支持。
<div className="fancy-button" onClick={e => console.log(e)}>Click</div>
除了使用 keydown 来恢复键盘支持外,还需要 tabIndex 来使 div 元素可访问。为了避免重载和实现浏览器已经提供的功能,应该首选原生表单控件。
<div className="fancy-button" onClick={e => console.log(e)} onKeyDown={e => e.code === 'Space' && console.log(e) } tabIndex="0">Click</div>
表单组件必须与另一个描述表单元素用途的元素相关联。这通常通过 label 元素实现。
<label htmlFor="myinput">Username:</label>
<input id="myinput" type="text" name="username" />
HTML 提供了各种元素来组织网页上的内容,屏幕阅读器可以识别这些元素。首选语义 HTML 用于良好的语义,为阅读器提供开箱即用的支持,当使用带有类的常规 div元素时这是不可能的。考虑以下对阅读器来说意义不大的示例。
<div className="header">
<div className="header-text">Header</div>
</div>
<div className="nav"></div>
<div className="main">
<div className="content">
</div>
<div className="sidebar">
</div>
</div>
<div className="footer">
</div>
可以使用内置屏幕阅读器支持的语义元素来实现相同的布局。
<header>
<h1>Header</h1>
</header>
<nav></nav>
<main>
<article></article>
<aside></aside>
</main>
<footer>
</footer>
ARIA 指的是“可访问的富 Internet 应用程序”,是一套用于填补语义 HTML 不足之处的套件。这些情况主要与富 UI 组件/小部件有关。尽管过去几年浏览器对日期选择器或颜色选择器等富 UI 组件的支持有所改进,但许多 Web 开发人员仍然使用由他们或 PrimeReact 等其他项目创建的派生自标准 HTML 元素的 UI 组件。这些类型的组件必须提供键盘和屏幕阅读器支持,后者是 WAI-ARIA 的用武之地。
ARIA 由角色、属性和特性组成。角色定义了元素的主要用途,例如 checkbox、dialog、tablist,而状态和特性定义了元素的元数据,例如 aria-checked、aria-disabled。
考虑以下原生复选框的情况。它具有内置的键盘和屏幕阅读器支持。
<input type="checkbox" value="Prime" name="ui" checked>
带有 CSS 动画的花式复选框可能看起来更具吸引力,但可能缺乏可访问性。下面的复选框可能会显示带有动画的选中字体图标,但它不是可选项卡,无法使用空格键选中,也无法被阅读器读取。
<div className="fancy-checkbox">
{checked && <i className="checked-icon"></i>}
</div>
另一种方法是使用 ARIA 角色来实现阅读器支持,并使用 JavaScript 来实现键盘支持。请注意,这里使用了 aria-labelledby 来替代带有 htmlFor 属性的 label 标签。
<span id="chk-label">Remember Me</span>
<div className="fancy-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-labelledby="chk-label"
onClick="() => toggle()" onKeyDown="(e) => e.keyCode === 32 && toggle()">
{checked && <i className="checked-icon"></i>}
</div>
然而,最佳实践是将语义化的 HTML 用于可访问性,同时保持用户体验的设计。这种方法包括隐藏一个原生的复选框以实现可访问性,并使用 JavaScript 事件来更新其状态。请注意,这里使用了 p-hidden-accessible,它将元素对用户隐藏,但不会对屏幕阅读器隐藏。
<label htmlFor="chkbox">Remember Me</label>
<div className="fancy-checkbox" onClick="() => toggle()">
<input className="p-hidden-accessible" type="checkbox" id="chkbox" onFocus="() => updateParentVisuals()" onBlur="() => updateParentVisuals()"
onKeyDown="(e) => e.keyCode === 32 && updateParentVisuals()">
{checked && <i className="checked-icon"></i>}
</div>
一个可用的示例是 PrimeReact 复选框,它可以使用 Tab 键进行访问,支持键盘操作,并且符合屏幕阅读器的要求。它不依赖于 ARIA 角色,而是依赖于一个隐藏的原生复选框。
网页上的颜色应力求达到至少 4.5:1 的对比度,并考虑选择不会引起视觉振动的颜色。
背景和前景内容之间的颜色对比度应足够大,以确保可读性。下面的示例显示了对比度良好和不良的两种情况。
颜色振动是由于选择相互之间可见度较低的颜色而导致的一种运动错觉。选择颜色组合时需要谨慎,以避免振动。
在深色设计方案中使用高饱和度颜色时应避免,因为它们会引起眼睛疲劳。应优先选择去饱和的颜色。