我还记得,当我学会如何仅用 CSS 创建悬停触发式子菜单时,我的兴奋之情。(这可能是在阅读了A List Apart 上的这篇 2003 年文章之后。)当时,这确实是 CSS 的一个小技巧。说真的。真是狂野的时代。
事情是这样的
<ul class="my-menu">
<li>
<a href="page-a.html">Page A</a>
<ul>
<li><a href="page-b.html">Page B</a></li>
<li><a href="page-c.html">Page C</a></li>
<li><a href="page-d.html">Page D</a></li>
</ul>
</li>
<!-- etc... -->
</ul>
/* Position submenus relative to parent list item */
.my-menu li {
position: relative;
}
.my-menu ul {
/* Hide my submenus by default */
display: none;
/* Position submenus, when open */
position: absolute;
left: 0;
top: 100%;
}
/* Look, Ma! No onclick handler! */
.my-menu li:hover > ul {
display: block;
}
如今,我们可以通过一个新技巧来提高仅用 CSS 创建的菜单的可访问性! 借助:focus-within
,菜单可以在使用键盘进行导航时打开和关闭。
/* No IE11 support */
.my-menu li:focus-within > ul {
display: block;
}
尝试使用鼠标和TAB
键在演示中移动。
但时代不同了,我已经不是当年我第一次学习这些技巧的我了。从那时起,我已经构建了许多网站,并且在可用性、可访问性和内容策略方面学到了更多知识。现在,我发现悬停触发式菜单在这三个方面都存在缺陷。因此,几年前,我停止构建悬停触发式子菜单,转而使用点击触发式子菜单。(从这里开始,我将它们简称为“悬停菜单”和“点击菜单”。)
我认为你也应该停止构建悬停菜单。我将告诉你原因。
悬停菜单不一致
看看我构建的某个网站上的真实菜单

很简单,对吧?箭头图标显示除了“主页”之外,每个项目都有子菜单。但是,如果这些子菜单出现在悬停时,菜单至少有四种可能的工作方式,而且你可能已经体验过所有四种。
- 最上面的“父级”菜单项链接到一个页面,每个子菜单项链接到另一个页面。对于上面的例子,“服务”将是一个唯一的页面,子菜单中的每个链接也将是唯一的页面。
但在某处,第二种非常常见的模式出现了。
- 父级项具有
href="#"
— 甚至根本没有href
😱 — ,而唯一有效的链接在子菜单中。在我们的示例中,“服务”仍然是一个链接,但单击它不会发生任何事情。
这种不一致 — 父级项是链接还是不是链接? — 导致我在观看人们使用网站时感到非常困惑。有些人直接跳过有用的顶级页面,假设这些项目不是链接。而另一些人则认为顶级链接是页面,并尝试单击它们。
这导致了你会遇到的第三种和第四种不太好的模式。我猜想,这些模式是为弥补前两种设置带来的混淆而演变的。
- 父级项和第一个子菜单项链接到同一个页面。更糟糕的是,父级项和第一个子菜单链接的链接文本不同,这违反了 WCAG 2.1 级 AA 可访问性标准。
- 父级项链接到一个页面,其中包含无用的填充内容或仅包含子菜单中的链接。这个页面本身对任何访问它的人都没有实际用处。
最后两种配置会浪费那些知道父级项目是链接的人的时间,因为它们包含了冗余或无用的内容。
这是一个展示所有四种可能的悬停菜单设置的图表。

访问者对悬停菜单感到困惑
无论我们如何实现悬停菜单,我们的访问者都可能会合理地想知道
- 我可以单击父级项目吗?
- 父级项目是否会链接到与第一个子菜单链接相同的页面?
- 即使父级项目是一个唯一的链接,它是否值得我花时间查看?
这让我们没有好的选择。它使我们无法满足雅各布的可使用性定律,即“用户希望您的网站与他们已经熟悉的其他所有网站一样工作”。在悬停菜单的实现方面没有标准,因此我们需要做一些不同的事情来提供一致的用户体验。
“分割按钮”菜单怎么样?
我见过的最不常见的菜单类型可能使用了“分割按钮”设计,其中父级项目是一个链接,一个单独的下拉菜单图标用于打开和关闭菜单。Twenty Fifteen 默认 WordPress 主题 使用了这种模式。因为它太不常见了,我发现访问者经常忽略顶级页面链接,研究表明用户不会认为标签和图标是独立可点击的。


那么,更好的选择是什么?点击触发式子菜单!
点击菜单来拯救
与其依赖悬停交互或其他“创造性”(且令人困惑)的解决方案,不如构建这样的菜单,其中父级项目是按钮,点击它们可以显示和隐藏子菜单。这立即解决了悬停菜单问题,因为点击菜单的工作方式非常明确。
- 网站访问者必须单击父级项目才能查看其子菜单。
- 所有链接都包含在子菜单中,除了没有子菜单的顶级项目(例如,“主页”。我们将在稍后处理这些顶级页面的情况。
仔细想想,点击菜单实际上是我们期望在大多数其他情况下出现的
- 使用触摸设备?悬停并不是真的存在。
- 使用应用程序菜单(例如,“文件”、“编辑”等)?这些菜单几乎不会在悬停时出现!
- 使用鼠标以外的任何东西?按
ENTER
键或使用任何类型的开关控制激活链接更像是单击,而不是:focus
相当于:hover
。
无论你的设备或输入方式是什么,“点击”都是一种更通用、更可靠的交互方式。让我们用它来让我们的网站菜单变得更加出色!
切换到点击菜单
我的直觉告诉我,很多网站最近都切换到了点击菜单。加入我们的行列吧!随着越来越多的网站做出这种改变,人们将再次形成对“网站如何工作”的简单且有用的期望(从而满足雅各布定律)。
当你第一次做出这种改变时,确实有些访问者可能会仍然期望悬停菜单。如果你问他们,他们甚至可能会说他们更喜欢悬停菜单。但是,我可以告诉你的是,我观察到人们使用点击菜单后,每个人都能很快明白并适应。
不要只相信我的话!美国网站设计系统 (USWDS) 的导航模式 使用了点击菜单。以下是他们的说法
避免使用悬停来展开下拉列表。悬停对于某些用户来说很困难,而且在触摸屏上无法使用。下拉列表应该在点击或使用键盘导航时展开。
归根结底,是用户意图。悬停状态的目的是指示某物可点击(带下划线的文本)… 点击的目的是实际执行某项操作,采取明确的行动。打开下拉菜单是一个明确的行动,并且应该只在点击时发生。
在同一篇文章中,有一个非常棒的见解
下拉链接中的插入符号相当于链接的下划线:它提供了一些关于点击此元素时将发生什么的提示。但不要将它误认为是提供足够的信息来在悬停时弹出下拉菜单。
所以我们并不是在探索未知领域。而且,英国政府设计系统 还提醒了我们:也许你根本不需要子菜单!他们的菜单只是一列链接,使用页面内的链接网格和手风琴来帮助访问者导航。说真的,在 CSS-Tricks 上也找不到子菜单!
点击菜单附带额外的好处!
你越使用点击菜单,你就会发现越多好处
- 您决定是否需要类别/概述/着陆页……还是不需要! 而不是强迫内容与菜单结构匹配,并使用作为其他链接父级的链接,您的内容策略和信息架构决定了您需要哪种类型的页面以及如何标记它们。如果服务概述对您的访客有帮助,请将“服务概述”或“所有服务”作为“服务”子菜单中的第一个项目。
- 子菜单保持打开状态,直到关闭。 悬停菜单有一种讨厌的方式,当人们碰到鼠标光标甚至只是 尝试点击子菜单链接 时就会消失。对于“飞出”而不是位于父项目下方的子菜单来说,尤其如此。点击菜单的持久性创造了更加“稳固”的体验,因此用户信任界面并且不会感到沮丧。
- 对于超级菜单,持久子菜单行为更为重要。 当访客需要更多时间来查看子菜单内容时,他们无法承受菜单意外关闭。
- “移动”和“桌面”菜单的 JavaScript 相同。 无论菜单隐藏在汉堡包后面还是在移动设备上可见,交互始终相同。我只需要更改我的 CSS 才能创建响应式点击菜单。
构建点击菜单
当我着手构建自己的可访问点击菜单脚本时,我发现没有一个关于如何做到这一点的标准。我自己的想法和代码受到以下方面的很大影响
- “链接+披露小部件导航” 作者:Adrian Roselli
- “标题演示” 作者:美国网络设计服务
- “菜单设计:帮助用户的 15 个 UX 指南清单” 作者:尼尔森诺曼集团
- “示例披露导航菜单” 在 ARIA 作者实践中
我对实施研究的主要收获
- 您单击以显示子菜单的元素应该是
<button>
,因为它不会链接到页面。 - 使用
aria-expanded
(在<button>
上!)来传达子菜单的打开和关闭状态。 - 使用
display: none
或visibility: hidden
,以便键盘用户在子菜单关闭时无法访问它们。 aria-controls
是垃圾,但您不妨添加它。- 不要 使用
role="menu"
(以及整个 ARIA 菜单模式)或aria-haspopup
。这些感觉相关,但它们不适用于构建导航菜单。 - 关闭打开的子菜单时
- 另一个子菜单打开
- 用户单击菜单外部
- 当焦点在打开的子菜单内时,用户按下
ESC
键。(并非所有用户都期望这样做,但我认为这是一个不错的补充。)
由于点击菜单需要 JavaScript,因此我们应该考虑如何在 JavaScript 出于任何原因失败的情况下 逐步增强 此菜单。毕竟,我们的经典悬停 CSS 技巧还是有用的!
我开始将我的点击菜单构建为一个仅使用 CSS 的悬停菜单,该菜单使用 li:hover > ul
和 li:focus-within > ul
来显示子菜单。然后,我使用 JavaScript 创建 <button>
元素,设置 aria
属性,并添加事件处理程序。这意味着菜单在没有 JavaScript 的情况下仍然可以正常工作,并且与我在首选 CMS WordPress 中构建的仅链接菜单配合得很好。
您可以查看 我使用的脚本,但我首先承认可能还有更好的脚本。重要的是您用真实用户测试它……并停止使用悬停菜单。😃
我一直在尝试使用 details 和 summary(是的,是的,针对旧浏览器的 polyfill)来创建菜单。summary 包含“组”名称(它永远不是链接),菜单项只是一些链接的无序列表。
然后,我在父容器上添加了一些 JS 以关闭任何已打开的同级 details,这由 data- 属性启用。这样,我就可以将组件重复用于不同的行为,例如将常见问题解答保持打开状态,直到关闭(默认浏览器行为)。
只是为了好玩,我添加了一个 data-animate 属性,它使用纯 CSS 对打开和关闭进行动画处理(请参阅 CSS Tricks 上的另一篇文章以了解这一点!)。
由于 details 的内容可以按你喜欢的方式进行样式设置,我甚至可以切换到使用 CSS 列(同样通过 data- 属性),如果列表对于平板电脑/桌面来说太高,同时保持最少的标记(只是围绕列表的额外包装容器)…
有人在 Twitter 上就这篇文章 提出了同样的想法,所以您不是唯一一个在想这个问题的人!这是 Github 使用的方法。
我想说这种方法可能用于可访问的菜单,但需要进行大量测试。在我查看的所有讨论和文章中,这种模式基本上从未出现过,所以充其量它还没有得到很好的研究或测试。
details/summary 与链接或按钮的不同语义也让我感到不安。这可能是可以解决的,但同样,我还没有看到任何人对此进行测试。
归根结底,我仍然推荐我的方法,因为它仍然提供无 JS 回退行为,并且在无障碍社区中得到了更详细的测试和讨论。我非常感谢这些巨人的肩膀,并相信他们的工作。
当您使用复选框和
:checked + .menu { display: block }
或类似的东西时,实际上并不需要。;)单选按钮比复选框更好。因为您希望一个菜单在另一个打开时关闭。
复选框技巧太酷了,用起来也很有趣!用它构建自定义复选框和单选按钮可能是我最喜欢的 CSS 任务之一。不出所料,CSS Tricks 已经多次介绍过它。这是一个 Chris 发布的示例集,其中包括菜单。也就是说,我想强调这篇文章中的一句话
由于
<form>
与<nav>
元素完全不同,因此在想出我的方法时,我没有考虑过这种模式。我认为在这里应用雅各布定律是很有意义的,尤其是在无障碍方面。屏幕阅读器用户和键盘导航用户比有视力或使用鼠标的用户受益更多,因为他们依赖的功能通常是不可见的或无法感知的。因此,在考虑无障碍性时,务必考虑语义以及访客最有可能在其他网站上遇到过什么。
在交互方面,我想不出比
<button>
和链接更基本的两个交互元素,因此它们非常适合构建一个新访客能够立即理解为导航菜单并轻松交互的界面。将
:hover > ul
和:focus-within > ul
结合起来,对我来说感觉像是一个足够好的无 JS 回退,并且支持每个网站访客都期望在菜单中遇到的语义元素(链接)。实际上,您可以跳过复选框和单选按钮,并使用带有 tabindex=”0″ 的 :focus-within
Asaf - 我也是这么想的,直到一位使用 Safari 的客户说菜单无法使用。
问题是,除非您将 Safari 的首选项设置为允许选项卡导航,否则“焦点”按通常理解/指定的方式根本无法使用。
Safari 焦点错误
自 2008 年以来一直存在……
好消息 - 看起来这个问题很快就会得到解决!
(https://blogs.igalia.com/mrego/2021/06/07/focus-visible-in-webkit-may-2021/)
我非常有兴趣在未来的项目中使用这种方法!只是希望设计团队能够接受这种方法……
您觉得是否有合适的方法来提出这个问题,而不会让人觉得“我知道最好,您的设计很糟糕”?
给他们发这篇文章?
有时,让大家充分参与这场奇怪的辩论可能很困难!可能最重要的是,您设法让人们超越了“但我不喜欢它”阶段的可用性讨论(这并非真正意义上的可用性讨论)。
我发现,当我列出这 4 种相互矛盾的悬停菜单实现时,人们通常会发现点击菜单的优势超过了不使用悬停菜单的低(且有争议的)成本。如果您的团队足够大,您可能会发现人们对悬停菜单的期望在团队内部甚至有所不同!我所知道的解决这个问题的唯一方法是完全改变方法,使用点击而不是悬停。
我刚刚提到了这篇文章中与我产生共鸣的一些观点,尤其是我们不能再假设在台式机大小的显示器上进行悬停,并询问设计团队的看法。每个人都同意,我们将从现在开始使用点击菜单。
嗨 Christopher,
作为一名对这篇文章感到非常高兴的 UX/UI 设计师,我相信说服设计团队加入不会有太大问题。他们可能一直在等待有人像这样清晰地表达问题和解决方案。
除此之外,如果可以轻松地设置一个交互式测试,那么对两个版本(点击 vs. 悬停或混合)进行用户测试会很有趣,并欢迎测试结果。几乎每个人都看到了基于证据的设计决策的价值。
我最讨厌的是标题上有链接的延迟悬停菜单…
我悬停,什么也没发生,我点击,菜单出现,然后“应用程序”开始过渡到标题链接指向的位置… 这简直令人恼火。
几乎和“获取垃圾邮件”总是被选中一样令人恼火。
我错过了顶层链接的解决方案吗?
如果文章不够清楚,请见谅。
“解决方案”是省略它们(如果它们只是填充内容)或将它们移动到带有清晰标签的子菜单中。
我认为还有另一种使用 HTML 书签的可能的悬停菜单设置,以及一种无需 JavaScript 即可实现点击菜单的方法。
请参阅这里
https://frugalwp.com/how-to-build-an-unambiguous-submenu-with-pure-css-and-html-no-javascript/
感谢您分享您的想法!我看到我们都喜欢使用
:focus-within
。虽然我喜欢在必要时只使用 CSS,但我学习子菜单导航的一部分是学习在必要时使用 JavaScript 才能制作出可访问的菜单。除了其他原因外,ARIA 属性向屏幕阅读器用户传达重要信息,键盘导航模式通过避免用户必须通过菜单中的每个链接进行TAB
来节省用户时间。(为此,提供一个跳过链接也很有帮助。这些都是非常互补的。)仅使用 CSS 作为渐进增强的第一步很棒,但我真的认为 JavaScript 是提供最可用和可访问的子菜单导航所必需的。
来自文章:“当你仔细想想,点击菜单实际上是我们已经对大多数其他情况的预期。”
[拍额头] 十多年来,我一直对没有人似乎在考虑如此明显的事情感到困惑。我的意思是,浏览器本身就具有功能完善的标准菜单。到 CSS 使 Web 下拉菜单成为可能时,下拉菜单的行为已经在可用性实验室(各种变化)中进行了广泛测试,并且在 Windows、Mac、NeXT、BeOS 等几乎所有操作系统中都已标准化:菜单与所有类型的按钮一致,等待被告知要打开哪个,也一致地可以通过鼠标、键盘、触控、语音、眼控等完成。
然后,一些 Web 开发人员决定创建无需您请求的菜单。您会在某个滚动位置点击一个链接,以便将鼠标移动到某个随机位置的新页面,然后触发某个随机菜单跳出并覆盖您正在寻找的内容,迫使您找到一种关闭它的方法,而不会意外触发另一个菜单并重新开始。如果您终于在页面其他部分看到了想要的内容并用鼠标移动到该位置:BLAT!在途中会触发另一个随机菜单。或者您的菜单排列方式是,尝试到达一个菜单会一直触发另一个附近的菜单,然后覆盖它(看看你,亚马逊!)
然后,其他每个人似乎都说,是的,我也希望访问我页面的访问者感觉他们刚跌跌撞撞地走进雷区。我不想让他们体验经过广泛测试、基于可用性研究的标准菜单行为,即在需要时点击菜单或按钮,而是希望他们体验到不知道会发生什么以及它会根据他们进入页面的位置以及他们是否使用鼠标或触控设备而有所不同的快感。
(工具提示是可以接受的,如果它们很小,不太可能覆盖您可能需要的任何内容。您仍然必须将它们的延迟设置得足够长,以确保在经过时不会触发。)
我们应该使用在 Win95 时代经过充分研究、广为人知、广受欢迎并已建立的菜单课程。如果这样可以帮助的话,我们可以假装它是一个新发明的概念,叫做“点击菜单”。
感谢您的评论!我绝对没有试图发明一个新概念。事实上,我几乎所有研究和工作都是为了避免做任何其他人没有做过和测试过的事情。
有趣的是,我从未找到过一个适用于这些菜单的好词。在可访问性领域,它们被称为“链接 + 公开小部件导航”,但这并不朗朗上口。还有很多关于使用“下拉”的歧义,所以我不希望使用它。
如果我错过了点击触发的子菜单导航的明显且广泛使用的名称,我很想了解它,以便我可以使用它,并追随那些走在我前面的人的脚步!
为什么不使用 :active 来点击打开?
:active
只在鼠标点击按下时应用,并在鼠标点击弹起时停止应用(大多数情况下)。因此,使用:active
只能在按住鼠标按钮时保持菜单打开。这是一个演示,向您展示
:active
应用的时间:https://codepen.io/mrwweb/pen/eYgYOVY?editors=1100很简单… 点击,拖动,然后松开。元素保持活动状态!超级简单… 只需要教你的访问者这种新的菜单激活方法。
/s,以防万一不清楚…
您可能会发现我的jsMenus 库 是一个有用的工具。它具有许多不错的功能,包括完整的键盘导航 - 尝试这里的演示。我没有尝试在没有 JavaScript 的情况下使它优雅地降级(因为我主要将其用于命令,而不是链接)。我还没有做太多添加属性和类以实现可访问性,但今天我修复了元素层次结构以使其更适合。欢迎反馈。
感谢您分享!一定要查看 ARIA 可以通过传达子菜单的打开/关闭状态来使菜单更易访问的方式!听起来这将是您的脚本的一个很好的补充!
我已经实现了您大部分主要建议。主要例外是 aria-controls,您似乎并不认为它特别有用(但如果需要,我可以添加它)。每个菜单项现在都是一个
<button>
;菜单项节点将按钮和任何子菜单都包裹起来;并且 aria-expanded 应设置相应的。大多数 aria 推荐的按键绑定都可以使用。(主要已知的缺少绑定是空格键和 Tab 键,但我还没有认真研究这些建议。)如果您要使用该库并有可访问性(或其他)问题,请发布一个问题。好文章!我有两个问题
1:为什么省略 aria-menu 模式?W3C 在他们的示例中使用它们了吗?如果不是导航,它有什么用?
2:你说“对顶层条目使用按钮”。在你的 codepen 中,你使用的是Services,为什么呢?
确实,那里甚至提供了用于导航菜单(在 role=menu 意义上)的多个演示示例。然而,这种模式一直存在争议。
有些人认为几乎不应该使用它们。特别是 Adrian Roselli 对此有强烈的感受,并在 WCAG 中提出了关于移除它们的议题。您可以在此处阅读他的观点:https://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html
在可访问性中经常发生这种情况,单个博客文章最终会产生很大影响,尤其是如果文章以某种语气撰写的话。那篇文章就是一个例子——如果你听到有人说菜单模式不应该被使用,我认为他们很可能在那里学到的,或者从某个在那里学到的人那里学到的,等等。这确实是我第一次在那里学到的。
那里的结论并没有被所有人接受,试图移除该模式或添加特定免责声明的尝试一直没有成功(多年来)。有些使用辅助技术的人更喜欢使用菜单行为进行导航,而有些则不。有些不用辅助技术的人更喜欢菜单行为,有些则不喜欢(无论如何,它们的体验都截然不同)。
无论如何,虽然有些人确实更喜欢菜单,但没有人会因为不使用它们而感到惊讶。鉴于菜单更复杂,出错的方式更多,即使有人不同意 Roselli 的所有结论,核心建议仍然有效。
@bathos 的回复很棒!
我承认阅读了 Adrian Roselli 关于这个问题的论点,并发现它们对我的观点有说服力并有影响。
我会说我自己使用的技术实际上归结为他们回应的结论
看起来很明显,我们可以在没有 role=”menu” 的情况下创建一个可靠的可用模式,而增加的复杂性似乎不值得我们可能获得的任何优势(在我看来)。
关于你关于按钮的第二个问题,“为顶级条目使用按钮”意味着你应该使用按钮元素而不是链接元素来表示显示子菜单的可点击项目。“服务”是导航菜单中第一个按钮的按钮文本(可访问名称)。希望这能澄清事情。
我喜欢这里的建议。菜单是互联网导航中如此重要的组成部分,它们应该是可用性关注的领域。
我认为糟糕的菜单之所以如此普遍,其中一个原因是开箱即用的 WordPress 将所有菜单项强制为链接。多年来,这一直是我对 WordPress 最大的抱怨之一。
很棒的文章,我最近得出了同样的结论。
我还没有找到一个清晰的解决方案,就是如何处理面包屑,当第一个导航级别没有专门的 URL 时。
我同意尼尔森的观点,即面包屑导航中除最后一项以外的所有项目都必须有 URL (https://www.nngroup.com/articles/breadcrumbs/ 第 6 节)。
然而,仅仅将第一个类别从面包屑中省略会导致对站点逻辑结构中当前位置的糟糕指示。
然后还有一个选项,将第一个级别菜单项作为仅重定向到第一个子页面的 URL。然而,这会导致非常不可预测的行为,我无法想象这是一种容易理解的良好体验。
我目前的结论是
– 对于层次结构 <3 级(并在菜单本身中清晰地指示位置)的站点,省略面包屑
– 在面包屑中点击一级项目时打开一个弹出窗口,显示子项目。虽然这不是常规的面包屑链接,但我认为它最符合预期(可以点击面包屑项目),最能指示当前位置,并重复主菜单本身已知的模式(点击一级展开二级项目列表)。
我非常好奇其他人如何处理点击菜单环境中的面包屑。
答案是减少省略内容页面,并首先为这些页面添加价值。“产品”页面不必是内容页面——它可以针对那些还不知道自己需要哪个产品细分的用户,并帮助他们找到它。
因此,我不会对内容页面如此不屑一顾。如果你有一个快速加载的网站,点击页面然后选择子项所需的时间可能与菜单展开、理解菜单和在菜单本身内进行第二次点击所需的时间相同或更快。
@Nathan,我完全同意!这绝对是我在文章中提出的选项之一。我认为重要的是,人们明确地决定是否需要登录/索引页面。
对于这个论点,我需要谨慎一点,原因有几个
1) 即使是最快的加载网站,页面刷新也几乎肯定更慢,我们始终希望考虑糟糕的网络和缓慢的互联网连接。
2) 加载页面以发现它不是你想要的东西,感觉上比打开子菜单更昂贵的 “交互成本”。
我使用 jQuery 已经有一段时间了,但最近我一直在尝试学习如何使用纯 JavaScript 代码来做这种事情。
它并不完美,但这是我对点击式下拉菜单的尝试
我选择不将菜单切换锚点转换为按钮,因为我的妻子(她使用各种屏幕阅读器,并且是她的工作场所的可访问性顾问)说,使用 role=”button” 并提供必要的适当 ARIA 属性就足够了。
我非常感谢任何关于如何改善菜单功能的建设性建议。
感谢您抽出时间和关注!
听起来你的妻子很了解情况,所以我不想质疑她。
我选择转换为按钮是因为 “ARIA 的第一条规则”,它直接写入规范
我宁愿使用按钮,而不是担心可能出现的边缘情况或我可能不知道的按钮行为。
感谢 @Mark Root-Wiley 撰写这篇文章!并感谢 @SiVal 对问题的恰如其分的描述。我目前正在我的 WordPress 客户主题中实现这一点。
我当前的客户想要三级子菜单。这里有没有人对如何实现这一点有想法或建议?
将子菜单项设为按钮可能没问题,但点击它会关闭子菜单列表,而 JavaScript 对我来说已经超出了能力范围。但是可能存在更好的解决方案,或者在我深入研究这个问题之前,我还应该知道其他事情。
希望将此功能纳入 WP 库的主题开发人员将不得不提出一个通用解决方案。我很期待看到可能实现的功能!
@clgolden – 很高兴你喜欢它!
多级子菜单是 我一直在考虑的事情,虽然你说得对,当前的脚本不支持它。这绝对是一种情况,我不喜欢嵌套子菜单的信息架构,所以我目前不支持它。我也喜欢通过不支持它,可以很容易地使用此脚本创建巨型菜单,其中单个子菜单可以包含多个可见级别的嵌套菜单项。
这是一个有趣的权衡,我认为你说得对,WordPress 主题默认情况下应该支持嵌套子菜单。
很棒的文章。我正在尝试在我的新网站上实现这一点,并且遇到了以下控制台错误
未捕获的 DOMException: 无法在“Element”上执行“closest”:‘#’ 不是有效的选择器。
它由 closeOpenMenu 函数调用。
在台式机上,每次点击带有下拉菜单的菜单时都会发生这种情况。它似乎仍然有效,但我不确定为什么它在我的机器上不断弹出,而在你的 CodePen 中却没有。
有什么想法吗?
嗨,Todd,
我认为这里的问题是包装你菜单的元素没有设置 ID。这是一个隐含的要求,我希望将来能够从脚本中移除或解决它(这是一个 GitHub 问题)。