无障碍风格指南就绪
在 Grafana,我们特别关注无障碍性,因此所有组件在编写时都必须考虑到这一点。
本文档旨在列出编写无障碍组件的最佳实践和建议。
Grafana/UI 组件
一些 grafana/ui 组件内置了特定的机制,使得编写无障碍组件更加容易。
表单元素
在使用表单元素时,一个重要的无障碍性考量是确保表单控件被正确地标记。为此,label
元素必须与相应的表单控件相关联。一种方法是为 label 提供一个 for
属性,该属性与表单控件的 id
属性匹配。
来自 grafana/ui 的表单组件提供了一种更简单的方法来实现这一点。在 Field
组件内部使用的表单元素,如果指定了 id
(对于 Select
,属性是 inputId
),则会正确地将 label
与它们关联起来。
例如,这段代码
<Field label="Name">
<Input id="name" placeholder="Enter a name" />
</Field>
将被渲染为(简化后)
<div>
<label for="name"> Name </label>
<input name="name" type="text" id="name" placeholder="Enter a name" value="" />
</div>
只要表单元素指定了唯一的 id
属性,在渲染时它就会自动具有无障碍性。
aria-live
指南
aria-live
应谨慎使用,因为它可能导致屏幕阅读器用户收到过多的公告。处理 aria-live
的主要责任应由消费者承担,grafana/ui 应提供正确的工具。
- Grafana/ui 组件不应包含
aria-live="assertive"
或role="alert"
aria-live
和role
属性可在 grafana/ui 组件中适当地暴露出来- 仅在向直接用户操作提供关键反馈时使用
aria-live="assertive"
或role="alert"
(例如,用户在搜索框中输入,但查询没有更多结果) - 对于不是直接与元素相关的用户操作导致更新的区域,请使用
aria-live="polite"
编写考虑无障碍性的测试
我们使用 React Testing Library (RTL) 编写单元测试。该库在构建时考虑了无障碍性,使得确保编写的代码对所有用户都可访问变得更容易。在使用 RTL 查询 DOM 元素时,优先使用 *ByRole
查询,因为它们更接近用户与页面交互的方式——无论是使用鼠标/视觉显示还是辅助技术。一般而言,如果代码在编写时考虑了无障碍性问题,那么 *ByRole
查询在大多数情况下都足够了。当然也有例外,因为并非所有元素都有定义的 ARIA 角色。
例如,对于这段代码
<Field label="Username">
<Input id="username" placeholder="Enter a name" value={'Test'} />
</Field>
测试用例可以如下所示
it('has username set', () => {
expect(screen.getByRole('textbox', { name: 'Username' })).toHaveValue('Test');
});
类型为 text
(默认类型值)的 Input 具有 textbox
角色,并且 name
选项不是赋予 input 元素的 name 属性,而是它们的可访问名称,在本例中即与 input 关联的 label 的文本内容。
引入无障碍性(a11y)错误的拉取请求:
我们使用 pa11y-ci 收集 项目中某些 URL 的无障碍性错误,每个 URL 都指定了错误阈值。
如果贡献引入了新的 a11y 错误,我们的持续集成将失败,阻止您合并到主分支。在这种情况下,有两种前进的选择:
- 检查流水线步骤
test-a11y-frontend-pr
中的错误日志,确定错误是什么,然后修复它。 - 在本地运行命令
yarn test:accessibility-report
,该命令会生成一个 HTML 无障碍性报告,然后访问包含您的更改的 URL,找出错误并修复它。请记住,一个本地 e2e Grafana 实例将在https://:3001
上运行。
您还可以通过在浏览器中安装 a11y 插件来避免引入 a11y 错误,例如 axe DevTools、Accessibility Insights for Web 等。