手风琴未通过可访问性检查
Accordion is failing accessibility check
我有一个使用 van11y-accessible-accordion-aria
渲染的手风琴
标记输出为:
<div className="c-accordion__items js-accordion accordion" data-accordion-cool-selectors="1" aria-multiselectable="true" role="tablist" id="z3j2diubs8r" data-hashaccordion-id="3o3nlqickh">
<!-- note role="tablist" above -->
<div className="c-accordion__item">
<h2 className="c-accordion__title accordion__title">
<button className="js-accordion__header accordion__header" role="tab" id="accordionz3j2diubs8r_tab1" aria-controls="accordionz3j2diubs8r_panel1" aria-selected="false" type="button" data-hashaccordion-id="3o3nlqickh" aria-expanded="false">
<!-- note role="tab" above -->
The Why
</button>
</h2>
<div className="c-accordion__item-components js-accordion__panel accordion__panel" role="tabpanel"
aria-labelledby="accordionz3j2diubs8r_tab1" id="accordionz3j2diubs8r_panel1" data-hashaccordion-id="3o3nlqickh"
aria-hidden="true">
<div className="c-accordion__item-content">
<p>Duis vel nibh at velit scelerisque suscipit. Donec vitae sapien ut libero venenatis faucibus. Quisque ut
nisi. Ut non enim eleifend felis pretium feugiat. Nulla sit amet est.
</p>
</div>
</div>
</div>
</div>
当我在 Chrome 中使用 Lighthouse 测试它的可访问性时,我收到了这些消息
Elements with an ARIA [role] that require children to contain a specific [role] are missing some or all of those required children.
Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. Learn more.
[role]s are not contained by their required parent element
Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. Learn more.
了解更多链接转到 https://web.dev/aria-required-children,下面显示的是他们建议的代码示例。
... 这意味着将 role="tablist"
作为父项,然后将 role="tab"
作为子项。
在这个问题中发布的代码中,与 https://web.dev/aria-required-children
中的示例相比,我似乎有正确的标记
所以我不知道为什么这没有通过可访问性检查。
role="tab"
必须是 role="tablist"
元素的直接后代(或包含在没有语义意义的元素中)。公平地说,这在 WAI-ARIA 规范中确实不清楚,但我自己以前遇到过这个问题。 (您可以使用 aria-owns
进行关联,但如果选项卡位于 tablist
元素之外,则更多)
因为您的 <button>
包裹在 <h2>
中,这打破了模式。
我已经对其进行了测试,它似乎可以在 JAWS 和 NVDA 中运行,但为了安全起见(因为有大量屏幕 readers,其中一些可能不喜欢您的实现)我会一个小的调整。
删除 <button>
周围的 <h2>
是一种选择,我可能会推荐这种选择。无论如何,在小部件上有多个 <h2>
元素没有多大意义,您应该在为该部分创建的选项卡上方使用标题。
第二个选择是让 <h2>
像按钮一样发挥作用,但这意味着要添加您自己的事件处理程序、焦点指示器和 tabindex="0"
以使其可聚焦。这样您就可以将 role="tab"
移动到 <h2>
本身,这会删除语义但保留在屏幕 reader.
中导航到它的能力
我个人不喜欢第二种选择,但我明白为什么有些人会选择这样做。
我建议的另一件事是将 tabs
和 tabpanel
放在 <ul>
和 <li>
.
中
对于不支持 tablist
的屏幕 reader,这意味着用户仍然会收到“3 个选项中的 1 个”等的通知。这样更容易理解他们有选项。
还建议每个 tabpanel
都有一个 tabindex="0"
以在选择选项卡后帮助导航。这是鼓励使 non-interactive 元素可聚焦的极少数情况之一。
您可能会发现 this W3 page on tab best practices 有用。
我有一个使用 van11y-accessible-accordion-aria
渲染的手风琴标记输出为:
<div className="c-accordion__items js-accordion accordion" data-accordion-cool-selectors="1" aria-multiselectable="true" role="tablist" id="z3j2diubs8r" data-hashaccordion-id="3o3nlqickh">
<!-- note role="tablist" above -->
<div className="c-accordion__item">
<h2 className="c-accordion__title accordion__title">
<button className="js-accordion__header accordion__header" role="tab" id="accordionz3j2diubs8r_tab1" aria-controls="accordionz3j2diubs8r_panel1" aria-selected="false" type="button" data-hashaccordion-id="3o3nlqickh" aria-expanded="false">
<!-- note role="tab" above -->
The Why
</button>
</h2>
<div className="c-accordion__item-components js-accordion__panel accordion__panel" role="tabpanel"
aria-labelledby="accordionz3j2diubs8r_tab1" id="accordionz3j2diubs8r_panel1" data-hashaccordion-id="3o3nlqickh"
aria-hidden="true">
<div className="c-accordion__item-content">
<p>Duis vel nibh at velit scelerisque suscipit. Donec vitae sapien ut libero venenatis faucibus. Quisque ut
nisi. Ut non enim eleifend felis pretium feugiat. Nulla sit amet est.
</p>
</div>
</div>
</div>
</div>
当我在 Chrome 中使用 Lighthouse 测试它的可访问性时,我收到了这些消息
Elements with an ARIA [role] that require children to contain a specific [role] are missing some or all of those required children. Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. Learn more.
[role]s are not contained by their required parent element Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. Learn more.
了解更多链接转到 https://web.dev/aria-required-children,下面显示的是他们建议的代码示例。
... 这意味着将 role="tablist"
作为父项,然后将 role="tab"
作为子项。
在这个问题中发布的代码中,与 https://web.dev/aria-required-children
中的示例相比,我似乎有正确的标记所以我不知道为什么这没有通过可访问性检查。
role="tab"
必须是 role="tablist"
元素的直接后代(或包含在没有语义意义的元素中)。公平地说,这在 WAI-ARIA 规范中确实不清楚,但我自己以前遇到过这个问题。 (您可以使用 aria-owns
进行关联,但如果选项卡位于 tablist
元素之外,则更多)
因为您的 <button>
包裹在 <h2>
中,这打破了模式。
我已经对其进行了测试,它似乎可以在 JAWS 和 NVDA 中运行,但为了安全起见(因为有大量屏幕 readers,其中一些可能不喜欢您的实现)我会一个小的调整。
删除 <button>
周围的 <h2>
是一种选择,我可能会推荐这种选择。无论如何,在小部件上有多个 <h2>
元素没有多大意义,您应该在为该部分创建的选项卡上方使用标题。
第二个选择是让 <h2>
像按钮一样发挥作用,但这意味着要添加您自己的事件处理程序、焦点指示器和 tabindex="0"
以使其可聚焦。这样您就可以将 role="tab"
移动到 <h2>
本身,这会删除语义但保留在屏幕 reader.
我个人不喜欢第二种选择,但我明白为什么有些人会选择这样做。
我建议的另一件事是将 tabs
和 tabpanel
放在 <ul>
和 <li>
.
对于不支持 tablist
的屏幕 reader,这意味着用户仍然会收到“3 个选项中的 1 个”等的通知。这样更容易理解他们有选项。
还建议每个 tabpanel
都有一个 tabindex="0"
以在选择选项卡后帮助导航。这是鼓励使 non-interactive 元素可聚焦的极少数情况之一。
您可能会发现 this W3 page on tab best practices 有用。