具有更宽容鼠标移动路径的下拉菜单

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

这是一个相当古老的用户体验概念,我已经有一段时间没听到有人讨论了,但在多级下拉菜单的情况下仍然适用。像鼠标这样的细粒度指针有时必须穿过非常狭窄的通道才能准确地到达下拉菜单中所需的位置。很容易出错(使鼠标指针离开路径)并因其关闭而受到惩罚。也许我们可以减少这种挫败感。

许多下拉菜单的设计使得当正确的区域不在 :hover 状态,或者发生 mouseleave 或 mouseout 事件时,包含所需菜单项的子菜单可能会关闭。
您可以到达所需的菜单项,但沿途有一些狭窄的通道。

基本的 CSS 方法

下拉菜单通常设计为通过父元素的 :hover 状态在 CSS 中显示子菜单。或者在 JavaScript 中使用 mouseenter / mouseover 事件并更改状态。所以诀窍是尝试阻止任何这些事件太容易发生。扩大走廊,就像那样。

我开始思考这个问题的全部原因是因为 CodePen 中主下拉菜单的子菜单走廊非常狭窄。为了在瓶颈处扩大它们,我在子菜单中添加了几个伪元素。如果鼠标移到这些元素上,不会发生任何事情,就像鼠标在子菜单中一样正常。

那里的红色只是为了演示这些伪元素的位置。

这是一种超轻量级的技术,只需要 CSS,我喜欢。唯一的轻微危险是您可能会覆盖大量相邻的菜单项,这意味着用户可能将鼠标悬停在合法的菜单项上而无法单击它。我想在很多情况下,他们只需稍微移动一下鼠标就可以了,但这绝对是在太小和太大之间进行权衡。

这可以追溯到 2005 年和一个经典的 Position is Everything 演示

以及可能的一个 Thierry Koblentz 演示

扩大 CSS 边界

John Gardner 创建了一种方法,所有菜单周围都有额外的空间,这些空间提供了宽容的悬停偏移。

看起来这个从互联网上删除了,抱歉!有很多 CodePen 上的 CSS 下拉菜单 可以探索。

(取消)悬停意图

您听说过“悬停意图”吗?这是一个概念,您不会立即对鼠标位置事件做出响应。您等待一小段时间,这样您就可以确定用户想要一个反应。这就像故意的延迟。它用于 UI 在没有它的情况下可能过于灵敏的情况。

我们可以称之为取消悬停意图的反面。就像我们立即对悬停事件做出反应,但在一段时间内不对悬停离开做出反应。在 CSS 中,您可以执行以下操作

.submenu {
  visibility: hidden;
  transition: 0.2s 1s; /* delay of 1 seconds on hover off */
}
.parent:hover .submenu {
  visibility: visible;
  transition-delay: 0s; /* react immediately on hover */
}

请注意,我们在这里使用 visibility 属性,它是可过渡的,而不是 display 属性,它不可过渡(奇怪的是)。

JavaScript 也当然能够实现取消悬停意图。您会像防抖一样处理它,除非经过一段时间,否则您不会调用执行关闭的函数。这可以通过一个 setTimeout 函数来实现,如果鼠标返回,则清除该函数。这过于简单化了,但是

var timer;

$(".parent").on("mouseover", function() {
  clearTimeout(timer);
  openSubmenu();
}).on("mouseleave", function() {
  timer = setTimeout(
    closeSubmenu
  , 1000);
});

function openSubmenu() {
  $(".submenu").addClass("open");
}
function closeSubmenu() {
  $(".submenu").removeClass("open");
}

这些取消悬停演示都没有通过扩展大小来解决走廊问题,而是通过宽容鼠标位置的快速偏差来解决。

避免狭窄的通道

没有规定子菜单下拉菜单需要向侧面展开。如果它们直接在下方打开,则通道保持宽阔。以下是 Timothy M. LeBlanc 的一个示例

使用 JavaScript 生成的三角形来美化

几年前,Ben Kames 发表了一篇关于此主题的精彩文章。他正在查看 Amazon.com 下拉菜单的响应速度,与使用延迟策略来处理可用性的其他下拉菜单相比。神奇之处在于数学!如果鼠标以合理的角度移动到新打开的子菜单,它就不会触发其他菜单项。视觉辅助

Ben 将其变成了一个 jQuery 插件,您可以 进行演示

他对这一点也非常正确

我相信这个问题在很多年前就被解决了,被遗忘,重新发现,再次解决,被遗忘,重新发现,再次解决。

这是我们行业中许多事情的悲哀真相。

Jon Neal 尝试删除 jQuery 依赖项并使用“重心坐标”改进数学。

Alex Popov 写信说他尝试了这个演示并改进了其功能。我没有时间重新加载所有内容到我的大脑中以弄清楚功能差异,但是如果您深入研究所有这些内容并正在查看可能性,这里有一个指向 Alex 版本的链接

其他问题

我认为一位智者曾经说过

“有时访问您网站的访客会有鼠标,有时则没有。”

因此,希望您的下拉菜单也能与触摸屏配合使用。您当然可以使它们正常工作!您还可以决定是否要将所有代码捆绑在一起以提高效率,或者是否需要某种功能检测来根据需要加载不同的脚本和样式(或两者的组合)。

键盘可访问性是下拉菜单的另一个经典问题。我只是不想让您认为帮助鼠标移动是您为获得良好的下拉菜单 UX 所需做的全部工作。总有改进的空间!

其他示例