繁体   English   中英

键盘a11y,用于多级导航菜单,其中按钮作为顶层项目

[英]Keyboard a11y for a multi-level navigation menu with buttons as top level items

我有一个2级的<nav>元素。 顶层项目用<button>标签标记,子项目用<a>标签标记,例如:

<nav role="navigation">
    <ul>
        <li>
            <button type="button">Category 1</button>

            <ul class="submenu">
                <li>
                    <a href="/cat1/subcat1">Subcategory 1</a>
                </li>
                <!-- ... other links -->
            </ul> <!-- /.submenu -->
        </li>
        <li>
            <button type="button">Category 2</button>

            <ul class="submenu">
                <li>
                    <a href="/cat2/subcat1">Subcategory 1</a>
                </li>
                <!-- ... other links -->
            </ul> <!-- /.submenu -->
        </li>
    </ul>
</nav>

顶级项目仅用作容器,没有链接到其自身的页面。

如何为该标记添加键盘辅助功能?

我目前考虑的选项有:

选项1

当顶层项目( <button>标签)被聚焦时,打开菜单。
当用户在子项之间切换时,请保持菜单处于打开状态。
当焦点移到另一个顶级项目或页面的其余部分时,关闭菜单。
另外,允许通过Escape键关闭菜单并转移焦点。

选项2

使用role="menu"将获得的焦点语义,即:
在顶层项目上按Enter,空格或向下箭头可打开菜单;
子项目上的向下箭头将焦点移至下一个项目;
子项目上的向上箭头将焦点移至上一个项目;
顶层项目上的向上箭头关闭菜单,然后;
在子项上时,按Esc键可以关闭菜单并将焦点转移到顶级项。

这样可以保留Tab键,以移至下一个顶级项目。

就个人而言,我更喜欢选项2,但我确实想知道它是否模糊了预期和显示之间的界限。

选项2最初感觉像是正确的键盘语义,但是应该保留单词“经典”意义上的“ true”菜单行为。 也就是说,诸如“文件,编辑,查看...”之类的菜单在其下列出了即时操作(例如“文件”>“打开”或“编辑”>“首选项”)。 选项2还意味着您的菜单必须是一个制表位,并且用户将使用向左/向右箭头从“类别1”移动到“类别2”。 我不想要你

对于导航“菜单”,它们并不是真正意义上的菜单。 它们只是导航到其他页面的链接的分组列表。

在W3C的菜单上有一个很棒的教程-https: //www.w3.org/WAI/tutorials/menus/ (如上所述,该教程的“ 应用程序菜单 ”中有一节讨论“经典”菜单,例如“文件,编辑,查看”。)

几乎总是建议使用按钮来执行即时操作,并使用链接导航到另一个页面,但是对于导航菜单,即使仅控制其他菜单项的下拉列表(通常是按钮的工作),也经常使用链接。 是否将按钮或链接用于顶层项目取决于您自己。 就个人而言,我将使用链接,以便<nav>中的所有元素均为链接,但这只是个人喜好。

无论如何,无论您对顶级项目使用按钮还是链接,该元素最初都应将aria-expanded设置为“ false”。 当用户选择顶级链接时,将aria-expanded更改为“ true”。

这是我期望的键盘行为:

  • 我应该能够在整个顶级项标签 从“类别1”选项卡切换到“类别2”。 (顶层项目的外观应该有一个“倒三角”,或一些图标,表示有东西在该菜单。)当一个顶级项目获得焦点不要打开子菜单。 这使得键盘用户很难进入最后一个顶级项目,因为他们必须浏览每个子菜单。
  • 当我在顶级项目上切换时,我应该能够按Enter键来展开下拉菜单。 焦点不应移到第一个子菜单项。 它应保留在顶层项目上。 Tab键应该带我到第一个子菜单项。 (如果您的DOM在顶级项目之后紧跟着子菜单项,那么您将获得“免费”这种制表行为。您的示例代码就是一个很好的例子。)然后,我可以在所有子菜单项中进行制表。
  • 如果在浏览子菜单时按esc键,则子菜单应关闭,焦点应移至打开子菜单的顶层项目(并且aria-expanded应当设置为“ false”)。
  • 如果我关闭标签的最后一个子菜单项,子菜单应该关闭和重点应转到下一个顶级项目(和aria-expanded应设置为“假”为打开子菜单中的顶级项目)。
  • 如果我在第一个子菜单项上移动 + Tab键 ,则焦点自然应该转到打开该子菜单的顶层项目。 子菜单仍应保持可见。 如果我再次Shift + Tab键然后在子菜单应该关闭和重点应转到以前的顶级项目(和aria-expanded应设置为“假”为打开子菜单中的顶级项目)。

乍一看听起来有些复杂,但实际上相当简单而优雅。 令人高兴的是,您将免费获得大多数制表行为。 您只需要实现enter打开子菜单, esc来关闭子菜单,以及一些onblur()处理程序来关闭子菜单即可。

作为一个侧面说明,你没有指定一个role对于已经分配了默认角色本地的HTML元素。 例如

<nav role="navigation">

应该只是

<nav>

<button type="button">Category 1</button>

应该只是

<button>Category 1</button>

<nav><button>的html5规范显示了默认角色,并专门说

(默认-_不设置_

(此外,您的<nav>还应该具有aria-labelaria-labelledby 。这在上述教程的“ 标签菜单 ”部分中已提及。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM