如何在用户键入时正确处理内联错误消息 (ARIA)?

How to properly handle inline error messages while the user is typing (ARIA)?

我们网站上有一个表单,其中包含在用户输入时使用 JavaScript 验证的字段(onChange 事件)。错误消息以红色文本显示在字段输入下方。

我们目前使用 aria-describedby 和 aria-invalid 属性将消息显示给 NVDA。 screen-reader 正确地宣布字段何时变为无效,但是它不会宣布字段何时再次有效。我们的测试团队强调这是有问题的。

我们还研究了将 role="alert" 添加到错误字段,但这似乎会在该字段无效时导致“重复说话”——它会因为 role="alert" 而宣布一次错误,又是因为 aria-describedby.

correct/recommended 处理此问题的方法是什么?

你很接近。您基本上需要对错误消息做两件事,以使每个人都可以访问它们 (WCAG 3.3.1)。

  1. 发生时公布错误信息
  2. 将错误消息与错误字段相关联

听起来您正在通过 aria-describedby and aria-invalid 处理 #2。如果用户错误地离开该字段然后返回,他们将听到该字段的标签(希望您通过 <label for="id"> 获得与该字段关联的标签) 他们因为 aria-describedby,所以会听到与之关联的消息作为字段的 描述 。由于 aria-invalid.

,他们还会听到该字段被宣布为 “无效”

对于 #1,您需要使用实时区域。使用 role="alert" is one way to get a live region but that causes an implicit aria-live="assertive"。通常不需要断言的实时区域,除非消息非常重要,以至于屏幕 reader 需要停止宣布它所说的任何内容来宣布您的消息。通常使用 aria-live="polite".

更好

在您的情况下,如果在用户键入时显示错误(例如,如果您有一个“创建密码”字段并且您想在他们键入时检查条件 [大写,小写,数字, special char, etc]), 然后使用 aria-live="polite" 将允许用户以正常速度键入并听到他们正在键入的字符,当他们暂停一秒钟时 then 您的留言将会被公布。

如果您改为使用 aria-live="assertive"(或 role="alert"),那么在用户输入时,如果您显示错误消息,用户输入的字符将不再被读出,因为屏幕 reader 将停止说出这些字符,而是宣布您的错误消息。断言消息 可能 清除屏幕 reader 将要说的任何未决通知,因此用户可能听不到他们在宣布错误时键入的任何其他字符,所以现在他们不会知道他们输入了什么。

来自 aria-live spec:

User agents or assistive technologies MAY choose to clear queued changes when an assertive change occurs.

无论如何,综上所述,您的代码应该如下所示:

<label for="myid">Enter stuff</label>
<input id="myid" aria-describedby="myerror">
<div aria-live="polite" id="myerror"></div>

当用户输入并且您的 onChange() 运行时,当您发现错误时,您将 aria-invalid 设置为 true 并将错误消息文本注入 <div id="myerror"> 元素,它会公布的。

你问题的第二部分是用户修复字段的时间。用户如何知道错误何时被清除?当用户输入并更正错误时,您将 aria-invalid 设置为 false 并清除 <div>有时切换 ARIA 属性的值时,会自动宣布更改。这种情况发生在 aria-expandedaria-checked 上,但通常 不会 发生在 aria-invalid 上(尽管如果发生的话可能会很好)。

因此,如果您想告诉用户该字段不再有错误,您需要一个 second aria-live 明显隐藏的区域仅用于宣布“解除警报”消息。当您清除 <div id="myerror"> 中的错误消息时,由于直播区域宣布内容发生变化,您的内容从错误消息变为空白文本,屏幕 reader 实际上没有任何要宣布的内容。我想它可以说“空白”,因为那是新内容,但这并没有真正告诉用户它不再有错误了。

因此,对于第二个实时区域,您可以在其中注入“未发现错误”或“错误已清除”或您的设计者认为合适的一些消息。所以代码现在是:

<label for="myid">Enter stuff</label>
<input id="myid" aria-describedby="myerror">
<div aria-live="polite" id="myerror"></div>
<div aria-live="polite" id="allclear" class="sr-only"></div>

当确定要清除错误时,您将文本插入 <div id="allclear"> 并且它会被宣布。除了注入 <div id="myerror"> 和设置 aria-invalid.

之外,您还必须更新错误检测代码以在发现错误时清除“allclear”消息

最后一部分是用在“allclear”上的“sr-only”class。这不是预定义的 class 而是 class 的通用名称,它可以明显地隐藏元素,以便有视力的用户看不到该元素(您不想实际看到“一切都清楚” " 消息),但屏幕 readers 仍然可以访问该文本。您可以在此处找到“sr-only”的示例定义,What is sr-only in Bootstrap 3?

我知道这看起来像很多信息,但是一旦你对所有信息进行编码,还不错。

作为最后的旁注,如果您的错误消息颜色是纯红色 #FF0000,那么在白色背景 (4:1) 上将没有足够的对比度。您需要稍微深一点的红色,例如 #ee0000 (4.5:1)。这将满足 WCAG 1.4.3