对于<a>或<li>,ARIA role ="menuitem"

Géz*_*éza 4 menu wai-aria

我找到了两种可能的解决方案:

  1. <li>标签应用role ="menuitem" :

    <li role="menuitem"><a ...>some menuitem</a></li>

  2. <a>标签应用role ="menuitem" :

    <li role="presentation"><a role="menuitem" ...>some menuitem</a></li>

我认为第二种解决方案是合乎逻辑的,但我不确定.我不能在更复杂的情况下使用它,只有2,因为子菜单不是<a>标记的子代:

<li role="menuitem"><a ...>some menuitem</a></li>
<li role="menuitem" aria-haspopup="true">
  <a ...>some menuitem with children </a>
  <div><ul>
    <li role="menuitem"><a ...>submenuitem</a></li>
    ...
  </ul></div>
</li>
Run Code Online (Sandbox Code Playgroud)

这是对的吗?它还有一些可能的改进吗?

HTML结构由我使用的框架定义,我无法更改它.

aar*_*ian 13

回答问题

如果您真正将操作系统风格的菜单应用于应用程序,那么您希望将其role放在应用程序上<a>.这是执行菜单项功能的项目(链接到另一个视图或页面或状态).

所以你的第二个建议是正确的:

<li role="presentation"><a role="menuitem" ...>some menuitem</a></li>

曲线球

现在说,我怀疑你真的不想要一个操作系统风格的菜单.要查看其中的内容,请查看WAI-ARIA创作实践项目2.14菜单或菜单栏.

通过调用这种菜单,您告诉熟练的屏幕阅读器用户,它将像操作系统菜单一样运行,这意味着您需要遵守下面的键盘命令(因此您必须对它们进行全部编码,ARIA不会只需让浏览器尊重他们).

相反,考虑只使用一个<nav>元素来保存你的列表(它将被宣布给屏幕阅读器并作为页面内导航的里程碑),保持列表语义到位(IOW,不要role=presentation像你想要的屏幕阅读器用户那样使用知道有多少项目,并根据您的需要在视觉上显示样式.

这样,您就不会为屏幕阅读器用户创建更糟糕的体验,以帮助他们(或满足检查表项目).

ARIA菜单键盘交互

  • menu打开或menubar接收焦点时,键盘焦点放在第一个项目上.所有项目都是可聚焦的,如4.6键盘导航内部组件中所述.
  • Enter:
    • 当焦点在menuitem具有子菜单的情况下,打开子菜单并将焦点放在其第一个项目上.
    • 否则,激活该项目并关闭菜单.
  • Space:
    • 当焦点位于a时menuitemcheckbox,在不关闭菜单的情况下更改状态.
    • 当焦点位于menuitemradio未选中且未关闭菜单时,检查焦点menuitemradio并取消选中menuitemradio同一组中的任何其他已检查元素.
    • (可选):当焦点位于menuitem具有子菜单的情况下时,打开子菜单并将焦点放在其第一个项目上.
    • (可选):当焦点位于menuitem没有子菜单的情况下时,激活menuitem并关闭菜单.
  • Down Arrow:
    • 当焦点位于a menuitem中时menubar,打开其子菜单并将焦点放在子菜单中的第一个项目上.
    • 当焦点在a中时menu,将焦点移动到下一个项目,可选择从最后一个到第一个.
  • Up Arrow:
    • 焦点位于a时menu,将焦点移至上一个项目,可选择从第一个到最后一个.
    • 当焦点在a中时menubar,什么都不做.
  • Right Arrow:
    • 当焦点在a中时menubar,将焦点移动到下一个项目,可选择从最后一个到第一个.
    • 当焦点位于具有子菜单的a menu和on中时menuitem,打开子菜单并将焦点放在其第一个项目上.
    • 当焦点位于menu没有子菜单的项目中时,请执行以下3个操作:
      1. 关闭子菜单和任何父菜单.
      2. 将焦点移动到下一个menuitemmenubar.
      3. 或者:(推荐)打开子菜单menuitem而不将焦点移动到子菜单,或打开子菜单menuitem并将焦点放在子菜单中的第一个项目上.
      请注意,如果menubar不存在,例如,菜单是从menubutton打开的,Right Arrow当焦点在没有子菜单的项目上时,将不会执行任何操作.
  • Left Arrow:
    • 焦点位于a时menubar,将焦点移至上一个项目,可选择从最后一个到第一个.
    • 当焦点位于a中项目的子菜单中时menu,关闭子菜单并将焦点返回到父项menuitem.
    • 当焦点位于a中项目的子菜单中时menubar,执行以下3个操作:
      1. 关闭子菜单.
      2. 将焦点移动到前menuitem一个menubar.
      3. 或者:(推荐)打开子菜单menuitem而不将焦点移动到子菜单,或打开子菜单menuitem并将焦点放在子菜单中的第一个项目上.
  • Home:如果不支持箭头键包装,请将焦点移动到当前menu或中的第一个项目menubar.
  • End:如果不支持箭头键包装,请将焦点移至当前menu或中的最后一项menubar.
  • 与可打印字符对应的任何键(可选):将焦点移动到当前菜单中的下一个菜单项,其标签以该可打印字符开头.
  • Escape:关闭包含焦点的菜单,并将焦点返回到元素或上下文,例如,菜单按钮或父项menuitem,从中打开菜单.
  • Tab:将焦点移动到选项卡序列中的下一个元素,如果具有焦点的项目不在a中menubar,则关闭其menu所有打开的父menu容器.
  • Shift + Tab:将焦点移动到选项卡序列中的上一个元素,如果具有焦点的项目不在a中menubar,则关闭其menu所有打开的父menu容器.

  • @RobinMétral 是的,这是错误的。`&lt;a&gt;` 需要被覆盖为 `menuitem`,`&lt;li&gt;` 的本机角色被覆盖。检查[APG模式](https://www.w3.org/TR/wai-aria-practices-1.1/examples/menubar/menubar-1/menubar-1.html)中的代码进行比较。另外,[不要使用 ARIA 菜单角色进行站点导航](http://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html)。 (3认同)