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

Mik*_*ike 1 html accessibility wcag wai-aria

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

目前,我们使用 aria-descriptedby 和 aria-invalid 属性将消息呈现给 NVDA。屏幕阅读器会正确地宣布字段何时无效,但不会宣布字段何时再次有效。我们的测试团队强调这是有问题的。

我们还研究了将 role="alert" 添加到错误字段,但这似乎会在该字段无效时导致“双声” - 它会因为 role="alert" 而宣布错误一次,并再次因为咏叹调描述。

处理这个问题的正确/推荐方法是什么?

slu*_*ous 5

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

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

听起来你正在通过aria-describedby和处理#2 aria-invalid。如果用户导航离开错误的字段然后返回,他们会听到该字段的标签(希望您通过 拥有与该字段关联的标签<label for="id">,并且他们会听到与其关联的消息作为字段的描述,因为的aria-describedby。他们还将听到该字段由于 而被宣布为“无效”aria-invalid

对于#1,您需要使用实时区域。使用role="alert"是获取活动区域的一种方法,但这会导致隐式aria-live="assertive". 通常不需要断言的活动区域,除非消息非常重要以至于屏幕阅读器需要停止朗读它所说的内容来宣布您的消息。一般情况下使用比较好aria-live="polite"

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

如果您改为使用aria-live="assertive"(或role="alert"),那么当用户键入时,如果您显示错误消息,则将不再读出用户正在键入的字符,因为屏幕阅读器将停止说出这些字符,而是会读出错误消息。断言消息可能会清除屏幕阅读器将要显示的任何待处理公告,因此用户在宣布错误时可能听不到他们键入的任何其他字符,因此现在他们不知道自己键入了什么。

aria-live规格来看

当发生断言更改时,用户代理或辅助技术可以选择清除排队的更改。

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

<label for="myid">Enter stuff</label>
<input id="myid" aria-describedby="myerror">
<div aria-live="polite" id="myerror"></div>
Run Code Online (Sandbox Code Playgroud)

当用户键入并且 onChange() 运行时,当您发现错误时,您将设置aria-invalid为 true 并将错误消息文本注入到<div id="myerror">元素中,然后它将被宣布。

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

因此,如果您想告诉用户该字段不再出错,则需要第二个明显隐藏的 aria-live 区域,该区域仅用于宣布“全部清除”消息。当您从 中清除错误消息时<div id="myerror">,由于活动区域宣布了内容更改,您的内容从错误消息更改为空白文本,屏幕阅读器实际上没有任何要宣布的内容。我想它可以说“空白”,因为这是新内容,但这并不能真正告诉用户它不再出错了。

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

最后一部分是“allclear”上使用的“sr-only”类。这不是一个预定义的类,而是一个类的通用名称,该类可以明显地隐藏某个元素,以便有视力的用户看不到该元素(您不想在屏幕上实际看到“全部清除”消息),但屏幕上会显示该元素。读者仍然可以访问文本。您可以在此处找到“sr-only”的示例定义,Bootstrap 3 中的 sr-only 是什么?

我知道这看起来有很多信息,但一旦你把它们全部编码起来,那就没那么糟糕了。

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