简体   繁体   English

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

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

I have a <nav> element with 2 levels. 我有一个2级的<nav>元素。 The top-level items are marked up with <button> tags and the child items with <a> tags, such as: 顶层项目用<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>

The top-level items are intended to act as containers only and do not have pages of their own to link to. 顶级项目仅用作容器,没有链接到其自身的页面。

How should I add keyboard accessibility to this markup? 如何为该标记添加键盘辅助功能?

Options I've thought about at the moment are: 我目前考虑的选项有:

Option 1 选项1

Open the menu when top-level items ( <button> tags) are focused. 当顶层项目( <button>标签)被聚焦时,打开菜单。
Keep the menu open as the user tabs through the child items. 当用户在子项之间切换时,请保持菜单处于打开状态。
Close the menu when the focus moves to another top-level item or the rest of the page. 当焦点移到另一个顶级项目或页面的其余部分时,关闭菜单。
Also, allow closing the menu via the Escape key and transfer focus. 另外,允许通过Escape键关闭菜单并转移焦点。

Option 2 选项2

Use the focus semantics that a role="menu" would get, namely: 使用role="menu"将获得的焦点语义,即:
Enter, Space or Down arrow on the top-level item open the menu; 在顶层项目上按Enter,空格或向下箭头可打开菜单;
Down arrow on a child item moves focus to the next item; 子项目上的向下箭头将焦点移至下一个项目;
Up arrow on a child item moves focus to the previous item; 子项目上的向上箭头将焦点移至上一个项目;
Up arrow on the top-level item closes the menu, and; 顶层项目上的向上箭头关闭菜单,然后;
Escape key while on a child item, closes the menu and transfers focus to the top-level item. 在子项上时,按Esc键可以关闭菜单并将焦点转移到顶级项。

This would allow the Tab key to be reserved for moving to the next top-level item. 这样可以保留Tab键,以移至下一个顶级项目。

Personally, I prefer Option 2, but I do wonder if it blurs the lines between what's expected and what's shown. 就个人而言,我更喜欢选项2,但我确实想知道它是否模糊了预期和显示之间的界限。

Option 2 initially feels like the right keyboard semantics but that behavior should be reserved for "true" menus in the classic sense of the word. 选项2最初感觉像是正确的键盘语义,但是应该保留单词“经典”意义上的“ true”菜单行为。 That is, menus such as "File, Edit, View..." that have immediate actions listed under them (such as File > Open or Edit > Preferences). 也就是说,诸如“文件,编辑,查看...”之类的菜单在其下列出了即时操作(例如“文件”>“打开”或“编辑”>“首选项”)。 Option 2 also means that your menu would have to be one tab stop and the user would use left/right arrows to move from "Category 1" to "Category 2". 选项2还意味着您的菜单必须是一个制表位,并且用户将使用向左/向右箭头从“类别1”移动到“类别2”。 I don't think you want that. 我不想要你

For navigation "menus", they're not really menus in the classic sense. 对于导航“菜单”,它们并不是真正意义上的菜单。 They're just a grouped list of links to navigate to other pages. 它们只是导航到其他页面的链接的分组列表。

There's an excellent tutorial on menus on W3C - https://www.w3.org/WAI/tutorials/menus/ . 在W3C的菜单上有一个很棒的教程-https: //www.w3.org/WAI/tutorials/menus/ (There's a section on " application menus " in that tutorial that talk about the "classic" menus such as "file, edit, view", as mentioned above.) (如上所述,该教程的“ 应用程序菜单 ”中有一节讨论“经典”菜单,例如“文件,编辑,查看”。)

I almost always recommend using buttons for immediate action things and links for navigating to another page, but with navigation menus, links are often used even if they only control the dropdown list of further menu items (which is usually a button's job). 几乎总是建议使用按钮来执行即时操作,并使用链接导航到另一个页面,但是对于导航菜单,即使仅控制其他菜单项的下拉列表(通常是按钮的工作),也经常使用链接。 Whether you use buttons or links for your top level items is up to you. 是否将按钮或链接用于顶层项目取决于您自己。 Personally, I would use links so that all the elements in the <nav> are links, but that's just personal preference. 就个人而言,我将使用链接,以便<nav>中的所有元素均为链接,但这只是个人喜好。

In any event, whether you use a button or a link for the top level items, the element should have aria-expanded set to "false" initially. 无论如何,无论您对顶级项目使用按钮还是链接,该元素最初都应将aria-expanded设置为“ false”。 When the user selects the top level link, change aria-expanded to "true". 当用户选择顶级链接时,将aria-expanded更改为“ true”。

Here's the keyboard behavior I would expect: 这是我期望的键盘行为:

  • I should be able to tab across the top level items. 我应该能够在整个顶级项标签 Tab from "Category 1" to "Category 2". 从“类别1”选项卡切换到“类别2”。 (The visual appearance of the top level items should have a "down triangle" or some icon that indicates there is something in that menu.) Do not open the submenu when a top level item receives focus. (顶层项目的外观应该有一个“倒三角”,或一些图标,表示有东西在该菜单。)当一个顶级项目获得焦点不要打开子菜单。 That makes it very difficult for keyboard users to get to the last top level item because they'd have to navigate through every submenu. 这使得键盘用户很难进入最后一个顶级项目,因为他们必须浏览每个子菜单。
  • As I tab across the top level items, I should be able to hit enter to expand the dropdown menu. 当我在顶级项目上切换时,我应该能够按Enter键来展开下拉菜单。 The focus should not be moved to the first submenu item. 焦点不应移到第一个子菜单项。 It should remain on the top level item. 它应保留在顶层项目上。 Pressing tab should take me to the first submenu item. Tab键应该带我到第一个子菜单项。 (If your DOM has the submenu items immediately after the top level items, you will get this tabbing behavior "for free". Your sample code is a good example.) I can then tab through all the submenu items. (如果您的DOM在顶级项目之后紧跟着子菜单项,那么您将获得“免费”这种制表行为。您的示例代码就是一个很好的例子。)然后,我可以在所有子菜单项中进行制表。
  • If I press esc while tabbing through the submenu, the submenu should dismiss and the focus should be moved to the top level item that opened the submenu (and aria-expanded should be set to "false" for the top level item). 如果在浏览子菜单时按esc键,则子菜单应关闭,焦点应移至打开子菜单的顶层项目(并且aria-expanded应当设置为“ false”)。
  • If I tab off the last submenu item, the submenu should close and the focus should go to the next top level item (and aria-expanded should be set to "false" for the top level item that opened the submenu). 如果我关闭标签的最后一个子菜单项,子菜单应该关闭和重点应转到下一个顶级项目(和aria-expanded应设置为“假”为打开子菜单中的顶级项目)。
  • If I shift + tab off the first submenu item, the focus should naturally go to the top level item that opened the submenu. 如果我在第一个子菜单项上移动 + Tab键 ,则焦点自然应该转到打开该子菜单的顶层项目。 The submenu should still remain visible. 子菜单仍应保持可见。 If I shift + tab again, then the submenu should close and the focus should go to the previous top level item (and aria-expanded should be set to "false" for the top level item that opened the submenu). 如果我再次Shift + Tab键然后在子菜单应该关闭和重点应转到以前的顶级项目(和aria-expanded应设置为“假”为打开子菜单中的顶级项目)。

It sounds a little complicated at first but is actually quite simple and elegant. 乍一看听起来有些复杂,但实际上相当简单而优雅。 The nice thing is that most of the tabbing behavior you'll get for free. 令人高兴的是,您将免费获得大多数制表行为。 You just have to implement enter to open the submenu, esc to close the submenu, and some onblur() handlers to close the submenus. 您只需要实现enter打开子菜单, esc来关闭子菜单,以及一些onblur()处理程序来关闭子菜单即可。

As a side note, you don't have to specify a role for native html elements that already have a default role assigned. 作为一个侧面说明,你没有指定一个role对于已经分配了默认角色本地的HTML元素。 For example 例如

<nav role="navigation">

should just be 应该只是

<nav>

and

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

should just be 应该只是

<button>Category 1</button>

The html5 spec for <nav> and <button> shows you the default role and specifically says <nav><button>的html5规范显示了默认角色,并专门说

(default - _do not set_ ) (默认-_不设置_

(Also, your <nav> should also have an aria-label or aria-labelledby . This is mentioned in the " Label menus " section of the tutorial mentioned above.) (此外,您的<nav>还应该具有aria-labelaria-labelledby 。这在上述教程的“ 标签菜单 ”部分中已提及。)

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

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