“aria-hidden 元素不包含可聚焦元素"显示模态时的问题 [英] "aria-hidden elements do not contain focusable elements" issue when modal is shown
问题描述
我在我的应用程序中使用 React Modal 并且当它打开时运行 aXe 辅助工具 给出以下错误:
这是因为 React modal 向应用程序的根元素添加了一个 aria-hidden=true"
(我的所有应用程序组件都在 div 下呈现,但不是 modal),但它不会更新选项卡索引或禁用每个可聚焦元素.
但是,React 模态会捕获键盘焦点,因此用户无法跳出模态并单击背景关闭模态.
所以我的问题是:
这真的是我需要解决的问题吗?或者这是一个误报,因为该工具不了解模态捕获焦点?
如果确实需要解决这个问题,我唯一的选择是手动更新选项卡索引还是禁用每个可聚焦元素?
谢谢!
模态框打开时的 HTML 看起来像这样:
解决方案 简答
将 aria-modal
添加到您的模态框将删除此警告.
长答案
我花了一段时间才明白为什么我们的模态框没有这个警告,而你的却有这个警告,因为我们使用了类似的标记.我们在模态框上使用 aria-modal
属性.
Axe 已更新为期望模态框上的 aria-modal
属性.aria-modal
目前有 平均支持,但它是一种很好的做法,因为它可以解决开发人员的错误(因为确实尊重它的屏幕阅读器/浏览器组合会自动为您捕获焦点!).
在模式之外隐藏项目
真正隐藏所有内容的唯一方法是将 tabindex=-1"
添加到每个交互项目中.
但实际上,如果用于向每个交互元素添加 tabindex=-1"
的 JS 函数遇到问题并且不会成功还原 tabindex
或将其删除.这意味着您让页面的某些部分完全无法访问!
很明显,你会在稳健"的 WCAG 上失败.POUR 的一部分.请不要这样做.
最好的折衷方案是在 <main>
和 <aside>
容器(任何顶级容器)上使用 aria-hidden
).然后在您的模式上使用 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">输入测试</label><输入 id="iTest"/></div>
I'm using React Modal in my application and when it is open running the aXe accessibility tool gives the following error:
aria-hidden elements do not contain focusable elements
This is because the React modal adds a aria-hidden="true"
to the root element of the application (the div all my apps components are rendered under, but not the modal), but it does not update the tab index or disable every focusable element.
However the React modal traps the keyboard focus, so the user can't tab out of the modal and clicking the background closes the modal.
So my question is:
Is this actually an issue I need to fix?
Or is this a false positive as the tool doesn't have knowledge of the modal trapping focus?
If this does need to be fixed, is my only option to manually update the tab index or disable every focusable element?
Thanks!
The HTML when the modal is open looks kinda like this:
<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>
解决方案 Short Answer
Adding aria-modal
to your modal will remove this warning.
Long Answer
It took me a while to realise why our modals do not have this warning but yours would as we employ similar markup. We use the aria-modal
property on our modals.
Axe has been updated to expect the aria-modal
property on a modal. aria-modal
has average support at the moment but it is a good practice as it counters developer mistakes (as screen reader / browser combos that do respect it will automatically trap focus for you!).
Hiding items outside a modal
The only way to truly hide everything is to add tabindex="-1"
to every single interactive item.
However in reality that is far more likely to cause a catastrophic accessibility issue if your JS function you use to add tabindex="-1"
to every interactive element encounters an issue and doesn't successfully revert the tabindex
or remove it. This would mean you leave parts of the page completely inaccessible!
Obviously you would then fail WCAG on the "Robust" part of POUR. Please don't do this.
The best compromise is to use aria-hidden
on the <main>
and <aside>
containers (any top level containers). Then use aria-modal
on your modal as this will trap focus in some browser / screen reader combos. That combination of aria
will provide the highest coverage for browser support.
Finally you should manage focus for people using the tab
key. This is our backup in case the above methods fail and for people not using a screen reader (i.e. people with dexterity or accuracy issues who can't use a mouse.)
If you need information on how to trap the tab focus within a modal I will provide a code sample but it is pretty straight forward.
Managing tab key focus will not stop screen reader users or misbehaving plugins from getting outside your modal (if the other methods fail) but believe me, if they have a problem with your site after you implement the above they will have bigger problems on other sites.
inert - a further string to your bow?
Finally as another backup we add inert
to the items outside of our modal. Support isn't great, but every little helps!
You can polyfill it if you want but I don't think it has moved outside of the draft spec yet so we just use it as is.
It is purely there as yet another add in and (hopefully) to future proof our legacy applications as inert
is a much needed and easy to understand attribute. It blocks screen readers access to items without changing visual design (basically aria-hidden
but as a standard attribute, with the advantage that it effectively removes all children from the accessibility tree.)
Example
Try removing the aria-modal="true"
from the following example and running Axe, the warning will return.
<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>
这篇关于“aria-hidden 元素不包含可聚焦元素"显示模态时的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文
相关文章
- “咏叹调隐藏元素不包含可聚焦元素"显示模态时的问题;
- “隐藏咏叹调的元素不包含可聚焦的元素".显示模态时的问题;
- JAWS 的 aria-hidden true 读取;
- 这些属性是什么:`aria-labelledby` 和 `aria-hidden`;
- GWT div aria-hidden不隐藏在IE;
- HTML'hidden'和'aria-hidden'属性之间有什么区别?;
- GWT div aria-hidden 不隐藏在 IE 中;
- 使HTML元素不可聚焦;
- aria-hidden = true是否表示您不必使用display:none?;
- 隐藏的aria是否足够或将其值设置为"true"?必需的(aria-hidden ="true");
- CSS设置是否在说:现在没有等效于aria-hidden ="true"?;
- WebDriver查找元素不包含属性;
- 为什么overflow:hidden展开父元素(包含浮动的子元素)?;
- 单击其他元素时模糊(不聚焦)某个元素;
- jQuery聚焦元素;
- 哪些HTML元素不能包含子节点?;
- 为什么父元素不包含边距?;
- 在可聚焦元素上编写箭头导航的指南?;
- XML元素不显示空值;
- 非对角阵列元素不显示;
- 使用 createElementNS 创建的元素不显示;
- 当使用selenium函数按名称查找元素时,元素不可交互,但当通过xpath方法使用find元素时,元素可工作;
- :: before伪元素时,锚元素不起作用;
- 当span元素不包含文本时,请填充占位符文本;
- 当id包含逗号时,jQuery get元素不起作用;
前端开发最新文章
- 为什么Chrome(在Electron内部)突然重定向到chrome-error:// chromewebdata?;
- 错误102(net :: ERR_CONNECTION_REFUSED):服务器拒绝连接;
- 如何解决'重定向已被CORS策略阻止:没有'Access-Control-Allow-Origin'标题'?;
- 如何处理“Uncaught(in promise)DOMException:play()失败,因为用户没有首先与文档交互。”在桌面上使用Chrome 66?;
- 警告:添加非被动事件侦听器到滚动阻塞'touchstart'事件;
- 如何在浏览器中播放.TS文件(视频/ MP2T媒体类型)?;
- 此请求已被阻止;内容必须通过HTTPS提供;
- 资源解释为样式表,但转换为MIME类型text / html(似乎与web服务器无关);
- 通过HTTPS加载页面但请求不安全的XMLHttpRequest端点;
- 拒绝从执行脚本'*',因为它的MIME类型(“应用/ JSON')不是可执行文件,并严格MIME类型检查被启用。;