什么是导航栏/菜单的 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” 用于外包装<div>
role="menubar" 用于<ul>
导航栏容器
role="menu" 用于二级 <ul>
容器
role="presentation" 用于一级和二级<li>
菜单项(在公开的可访问菜单栏结构中不需要它们)
role="menuitem" 用于一级和二级<a>
菜单项
属性:
aria-haspopup="true" 用于具有子菜单的一级<a>
菜单项
aria-labelledby="上一个<a>
菜单项的ID" 用于二级<ul>
容器
州:
aria-selected="true" 在当前访问的第一级或第二级<a>
项目上; aria-selected="false" 在其他 <a>
项目上。那就是强制执行“选定当前页面”的概念
aria-expanded="true/false" 用于二级 <ul>
容器
aria-hidden="true/false" 用于二级 <ul>
容器
aria-activedescendant="" 用于主 <ul>
导航栏容器。这是使用 tabindex 的替代方法
tabindex=0 当前访问的<a>
项目; tabindex=-1 在其他 <a>
项目上。那是为了在切换到导航栏时首先关注当前页面。它是使用 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] > li[role=presentation] > a[role=menuitem]
的示例。干得好。
实际上,“1 of 1”问题出现在我尝试ul[role=menu] > li > a[role=menuitem]
时。可以肯定的是,大多数人都在推荐ul[role=menu] > li[role=menuitem] > 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-posinset
和aria-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进行遍历实现,封装菜单的请求工具类