什么是导航栏/菜单的 WAI-ARIA 兼容实现

Posted

技术标签:

【中文标题】什么是导航栏/菜单的 WAI-ARIA 兼容实现【英文标题】:What is a WAI-ARIA compliant implementation for navigation bar/menu 【发布时间】:2012-08-30 00:51:24 【问题描述】:

我们正在实施(即添加)对 Web 门户主导航菜单的 WAI-ARIA 支持。菜单是这里显示的:

菜单是通过经典的<ul> / <li> / <a> DOM 树实现的,用 CSS 设置样式看起来像水平标签。

这种小部件的 WAI-ARIA 兼容实现是什么?

我已经阅读了 w3org 提供的最新 WAI-ARIA 规范的许多部分,以获得一般的理解、分类等。 然后,我阅读了几个 UI 小部件实现的示例。我找不到任何专门针对此类 CSS 导航菜单的示例。我经常发现的最接近的小部件是 Menu、MenuBar 和 TabPanel。当然,我还查看了Free ARIA Community group(这个问题最初发布的地方)。

我会说这些小部件中的 none 与 (CSS) 导航菜单完全匹配。例如,TabPanel 可能控制页面中的某些内容(--> aria-controls),也可能是 MenuBar;但我完全不确定导航菜单控制页面中的内容(它控制要显示的下一页)。无需进一步说明,还有一些其他差异。 参考文献在文章末尾。如果有人作为导航菜单的更好(或更合适)示例,我们将很高兴了解它们。

参考文献

https://developer.mozilla.org/en-US/docs/Accessibility/ARIA/ARIA_Test_Cases#Menubar_and_Menu http://wiki.jqueryui.com/w/page/38666403/Menubar http://www.oaa-accessibility.org/examplep/menubar2/ http://test.cita.illinois.edu/aria/menubar/ http://dev.aol.com/dhtml_style_guide#menu http://whatsock.com/modules/aria_tabs_menu_modules/demo.htm http://www.w3.org/TR/wai-aria-practices/#menu http://www.w3.org/TR/wai-aria/roles http://www-03.ibm.com/able/resources/wai_aria_intro.html

【问题讨论】:

【参考方案1】:

一个可能的实现是:

HTML 结构:

<div> <!-- Outer wrapper -->
  <ul> <!-- Main navigation bar container -->
    <li> <!-- First-level item without submenu -->
      <a> <!-- Destination URL -->
      </a>
    </li>
    <li> <!-- First-level item with submenu -->
      <a> <!-- Destination URL -->
      </a>
      <ul> <!-- Second-level menu container -->
        <li> <!-- Second-level item -->
          <a>
          </a> <!-- Destination URL -->
        </li>
      </ul>
    </li>
  </ul>
</div>

角色:

role=”navigation” 用于外包装&lt;div&gt; role="menubar" 用于&lt;ul&gt; 导航栏容器 role="menu" 用于二级 &lt;ul&gt; 容器 role="presentation" 用于一级和二级&lt;li&gt; 菜单项(在公开的可访问菜单栏结构中不需要它们) role="menuitem" 用于一级和二级&lt;a&gt; 菜单项

属性:

aria-haspopup="true" 用于具有子菜单的一级&lt;a&gt; 菜单项 aria-labelledby="上一个&lt;a&gt; 菜单项的ID" 用于二级&lt;ul&gt; 容器

州:

aria-selected="true" 在当前访问的第一级或第二级&lt;a&gt; 项目上; aria-selected="false" 在其他 &lt;a&gt; 项目上。那就是强制执行“选定当前页面”的概念 aria-expanded="true/false" 用于二级 &lt;ul&gt; 容器 aria-hidden="true/false" 用于二级 &lt;ul&gt; 容器 aria-activedescendant="" 用于主 &lt;ul&gt; 导航栏容器。这是使用 tabindex 的替代方法 tabindex=0 当前访问的&lt;a&gt; 项目; tabindex=-1 在其他 &lt;a&gt; 项目上。那是为了在切换到导航栏时首先关注当前页面。它是使用 aria-activedescendant 的替代方法

键盘:

选项卡:将焦点从 Web 应用程序中的其他点移入/移出菜单。 Shift+Tab:以相反的顺序将焦点从 Web 应用程序中的其他点移入/移出菜单。 右箭头:下一个导航栏项 左箭头:上一个导航栏项 Enter:激活当前聚焦的项目(即导航到相应的 URL) 空格:激活当前聚焦的项目(即导航到相应的 URL)

2014 年 8 月:aria-selected Vs menuitem

回复@Joshua Muheim 评论:现在我可以看到from here 以及his reference,aria-selected 属性不允许用于menuitem 角色。 正如我从最近的SO answer 中读到的,考虑到当前的情况,有一些解决方案,并且还有一个新的提议属性。

【讨论】:

在阅读您的回答之前,我几乎准备放弃考虑不周的 aria 规格。对我来说,这是我的菜单中缺少的“演示”角色,这导致了奇怪的行为,例如每个菜单项被读出为“1 of 1”而不是“1 of [length]”。我在网上看到的大多数示例都导致了这种不良行为,除了您的答案之外,我没有找到任何说 ul[role=menu] &gt; li[role=presentation] &gt; a[role=menuitem] 的示例。干得好。 实际上,“1 of 1”问题出现在我尝试ul[role=menu] &gt; li &gt; a[role=menuitem] 时。可以肯定的是,大多数人都在推荐ul[role=menu] &gt; li[role=menuitem] &gt; a,这根本不起作用!它会读取菜单项,但由于没有关注链接,因此您无法带着它们去任何地方。 很高兴它有帮助!据我所知,每次插入一些(嵌套)节点时,都需要 xxx[role=presentation] 仅出于 aestetichal 目的,即定位、显示/隐藏、背景着色等。但从 content 的角度来看,这些节点毫无意义,因此您可以将它们标记为任何辅助工具。 是否也需要定义application 角色?此外,在使用屏幕阅读器 (SR) 时,例如具有 menuitem 角色的 JAWS 元素(例如锚链接)将在 SR 快捷方式列表中被忽略。 如果某些***菜单项不是链接,而是仅用于打开子菜单的按钮,应该如何处理?【参考方案2】:

ARIA 设计模式为一系列自定义控件提供了预期的 UI 行为http://www.w3.org/TR/wai-aria-practices/#aria_ex 使用 esc 键关闭并在关闭时返回触发元素是跨桌面和 Web 的标准 UI。在任何 Google 文档应用程序上试用(例如)。

【讨论】:

【参考方案3】:

您可以通过将aria-posinsetaria-setsize 属性添加到具有role=menuitem 的元素来获得一个宣布“X of Y”信息的菜单。

【讨论】:

感谢分享。我认为如果菜单 DOM 发生动态变化可能对其他人有帮助。我可以从here 中读到“如果集合中的所有元素都存在于 DOM 中,则不需要” 这更像是一个评论而不是一个答案。【参考方案4】:

+Escape 键应该关闭打开的菜单并将焦点返回到打开它的元素。

【讨论】:

距离我上次考虑这些功能已经有一段时间了。乍一看,使用 Escape 键关闭打开的菜单似乎很合适(我不记得在搜索过程中是否已经看到过)。我不确定用 Esc 关闭菜单后会发生什么:您的建议(将焦点返回到打开它的元素)对我来说似乎不合适。 Escape 是关闭的标准。 access.aol.com/dhtml-style-guide-working-group/#menu 这更像是一个评论而不是一个答案。【参考方案5】:

退出关闭是一种标准的回归方式,它是许多用户的预期行为。

【讨论】:

这更像是一个评论而不是一个答案。

以上是关于什么是导航栏/菜单的 WAI-ARIA 兼容实现的主要内容,如果未能解决你的问题,请参考以下文章

Vue的导航栏通过v-for进行遍历实现,封装菜单的请求工具类

html css 求助大神:导航栏菜单问题,二级菜单内容会遮盖掉后面的一级菜单栏选项。

jquery实现简易大气3D导航下拉菜单菜单栏效果

HTML+CSS实现网页的导航栏和下拉菜单

vue菜单切换导航栏不见了

网页导航菜单的子菜单平铺(带背景栏)实现