跳至主要内容

无障碍风格指南
就绪

在 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-liverole 属性可在 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 等。