显示模态时“aria-hidden 元素不包含可聚焦元素”问题

IT技术 javascript reactjs modal-dialog accessibility web-accessibility
2021-05-14 14:42:44

在我的应用程序中使用React Modal,当它打开时,运行ax 辅助功能工具会出现以下错误:

咏叹调隐藏元素不包含可聚焦元素

这是因为 React 模态aria-hidden="true"向应用程序的根元素添加了一个(我的所有应用程序组件都在 div 下呈现,但不是模态),但它不会更新选项卡索引或禁用每个可聚焦元素。

然而,React 模态会捕获键盘焦点,因此用户无法退出模态并单击背景关闭模态。

所以我的问题是:

这实际上是我需要解决的问题吗?或者这是一个误报,因为该工具不了解模态捕获焦点?

如果确实需要修复此问题,我是手动更新选项卡索引或禁用每个可聚焦元素的唯一选择吗?

谢谢!

模式打开时的 HTML 看起来有点像这样:

<div data-react-modal-body-trap="" tabindex="0" style="position: absolute; opacity: 0;"></div>
<div id="root" aria-hidden="true">application content</div>
<div class="ReactModalPortal">
    <div class="ReactModal__Overlay ReactModal__Overlay--after-open modal-overlay-6fODnA">
        <div tabindex="-1" role="dialog">modal content</div>
    </div>
</div>
3个回答

简答

添加aria-modal到您的模态将删除此警告。

长答案

我花了一段时间才意识到为什么我们的模态没有这个警告,但你的会有,因为我们使用了类似的标记。我们aria-modal在模态上使用该属性。

Ax 已更新为期望在aria-modal模态上使用属性。aria-modal目前有平均支持,但这是一个很好的做法,因为它可以解决开发人员的错误(因为屏幕阅读器/浏览器组合确实尊重它会自动为您捕获焦点!)。

在模态之外隐藏项目

真正隐藏所有内容的唯一方法是添加tabindex="-1"到每个交互式项目中。

然而实际上,如果您用来添加tabindex="-1"到每个交互元素的JS 函数遇到问题并且没有成功恢复tabindex或删除它,那么这更有可能导致灾难性的可访问性问题这意味着您将完全无法访问页面的某些部分!

很明显,你会在 POUR 的“Robust”部分通过 WCAG。请不要这样做。

最好的折衷方法是aria-hidden<main><aside>容器(任何顶级容器)上使用。然后aria-modal在您的模态上使用,因为这会在某些浏览器/屏幕阅读器组合中捕获焦点。这种组合aria将为浏览器支持提供最高的覆盖范围。

最后,您应该为使用tab密钥的人管理焦点这是我们在上述方法失败的情况下以及不使用屏幕阅读器的人(即无法使用鼠标的灵巧性或准确性问题的人)的备份。

如果您需要有关如何在模态中捕获选项卡焦点的信息,我将提供一个代码示例,但它非常简单。

管理选项卡键焦点不会阻止屏幕阅读器用户或行为不端的插件超出您的模式(如果其他方法失败)但相信我,如果在您实施上述方法后他们对您的网站有问题,他们将在其他网站上遇到更大的问题.

惰性 - 你的弓的另一根弦?

最后作为另一个备份,我们添加inert到我们模态之外的项目中。支持不是很好,但每一点都有帮助!

如果您愿意,您可以对它进行 polyfill,但我认为它尚未超出草案规范,所以我们只是按原样使用它。

它纯粹是另一个补充,并且(希望)将来证明我们的遗留应用程序inert是一个非常需要且易于理解的属性。它在不改变视觉设计的情况下阻止屏幕阅读器访问项目(基本上aria-hidden但作为标准属性,其优点是它可以有效地从可访问性树中删除所有子项。)

例子

尝试aria-modal="true"从以下示例中删除并运行 Axe,警告将返回。

<main aria-hidden="true" inert><a href="https://google.com">test</a></main>
<div class="modal" aria-hidden="false" aria-modal="true">
    <label for="iTest">input test</label>
    <input id="iTest"/>
</div>

这实际上是我需要解决的问题吗?或者这是一个误报,因为该工具不了解模态捕获焦点?

如果未禁用(例如通过删除 tabindex),列出页面中所有链接的插件仍将列出链接。

在处理可访问性时,您必须始终考虑不依赖 ARIA 的自定义插件可以或将会存在。

ARIA 主要由屏幕阅读器使用:它不是辅助技术的必要条件,而是它们提高可访问性的覆盖层。

例如,眼动追踪设备也可能在给定位置触发第一个可点击元素,并且由于插件的覆盖层不在 Tab 键顺序中,它可能会激活后面的元素。

第三个考虑因素:一些付费墙绕过保护或反广告插件可能会自动删除覆盖。

您会收到警告,因为当aria-hidden="true"设置为根元素时,您的页面可能具有可聚焦元素,这违反了此规则。

因此,为避免这种情况,您始终可以ariaHideApp={false}在不会设置的模态中进行设置,aria-hidden="true"并且您仍然会将注意力困在打开的模态中。

http://reactcommunity.org/react-modal/accessibility/