以下是 Micah Miller-Eshleman 的客座文章。Micah 设计了“优先级+导航”概念的一个变体,并在其工作的大学的生产环境中使用它。我一直喜欢了解设计模式背后的思考和创建过程,尤其是在它在现实世界中发挥作用的时候。
在小屏幕上显示较长的导航菜单很棘手。汉堡菜单随处可见,尽管 经常被劝阻使用。在每个断点显示“刚刚好”的导航感觉像是一项不可能完成的任务。对于需要适应任意数量菜单项的模板开发人员来说尤其如此。
优先级+设计模式 旨在在给定任意屏幕宽度的情况下显示尽可能多的项目,同时使其余项目可以通过单击即可访问。我将介绍我在 戈申学院 工作时进行的实现,其中包括下拉菜单和水平滚动,这是我在其他地方从未见过的。

1. 使用纯 CSS 实现带有固定项目的水平滚动
让我们从一个简单的水平滚动菜单开始
查看 CodePen 上 Micah Miller-Eshleman (@pranksinatra) 编写的 带有固定项目的优先级+导航。
(对于好奇的人,我正在使用 BEM 命名约定 作为类的名称,并使用 PostCSS 来实现一些简单的便利功能,例如嵌套和变量。)
请注意,在上面的演示中,如何调整屏幕宽度在 480px 以上/以下切换“GC Admissions”(第一个菜单项)的固定性。这是通过使用两个包装器实现的:一个外部包装器包含所有在 <480px 宽度下可滚动的菜单项,以及一个内部包装器包含所有非固定菜单项并在 >480px 宽度下可滚动。
2. 添加按钮和下拉菜单
在这里,我通过添加下拉菜单和点击滚动按钮扩展了之前的演示。我需要一些 JavaScript 来帮助实现滚动功能。
查看 CodePen 上 Micah Miller-Eshleman (@pranksinatra) 编写的 带有下拉菜单和滚动按钮的优先级+导航。
关于依赖项的快速说明:我内联了一个部分 classList、performance.now 和 requestAnimationFrame polyfill 用于 IE9+。 Font Face Observer 用于检测 Source Sans Pro 字体 何时加载。jQuery 通过使用 focusin() 和 focusout() 绑定来监听其子链接的 :focus 状态,从而帮助使下拉菜单可通过 Tab 键进行导航。请异步加载它(或找到更轻量级的替代方案)。
2a. 点击滚动按钮
按钮不仅对于启用鼠标和键盘用户的水平滚动很重要,而且对于指示滚动是可能的也很重要。这个概念借鉴于 Apple.com iPhone 页面

从根本上说,按钮点击通过更新相关包装器的 scrollLeft
属性来滚动菜单项。然后使用缓动函数对其进行动画处理,以模拟平滑的“动量”滚动。
您还会注意到一些显示/隐藏按钮、确定要滚动哪个包装器等的逻辑。为了做出这些决定,我们监听菜单的水平滚动位置和窗口的宽度(使用 去抖事件处理程序 来提高性能)。
2b. 水平滚动器上的下拉菜单
构建水平滚动下拉菜单证明是这个项目中最具挑战性的部分。
菜单的基本 HTML 结构由一个可滚动的包装器组成,该包装器包含菜单项列表,其中一些包含下拉菜单。菜单项是相对定位的,它们的下拉菜单是绝对定位的,因此它们作为一个单元滚动,但不会影响彼此的宽度。
必须为包装器指定一个显式高度,以防止下拉菜单被截断。然后我们遇到一个问题,即有一个非常高的包装器,要么向下推,要么覆盖后续内容。
查看 CodePen 上 Micah Miller-Eshleman (@pranksinatra) 编写的 定位可滚动包装器。
我选择的方法是使菜单在与之交互之前保持折叠状态,此时我们立即过渡到状态 #3(反之亦然)。这是通过侦听组件和包装器的 mouseover
和 touchstart
事件来实现的。
演示有意简化,只使用了一个包装器。对于多个包装器,我实际上是在 .nav
组件上切换 overflow 属性(hidden/visible),而不是单个包装器的高度,但底层概念是一样的。
如果您发现了更优雅的方法来实现这一点,我洗耳恭听!
如果它能自动滚动就更好了。边缘上的 20px 可以作为悬停时的滚动按钮。
我同意,手动滚动相当麻烦。偶然发现了这个使用鼠标滚动的优先级滚动菜单:http://dynamicdrive.com/dynamicindex1/priorityscrollmenu.htm 在移动设备上也能很好地工作,但遗憾的是它不支持下拉菜单。
我们确实需要更好的菜单。也许有一天每个页面只需要一个操作按钮,并且只要知道我们希望它做什么就行了 :)
嘿,Luke,感谢你的反馈。我同意,使用鼠标点击按钮进行滚动非常乏味!
此演示中的滚动功能针对移动触摸屏进行了优化,而不是桌面用户,假设这些用户的屏幕足够宽,除非菜单非常长,否则他们不应该需要滚动(此时,减少菜单项的数量可能是最佳的 UX 决策)。
话虽如此,我相信确实存在一些我的假设失效的合法用例,并且 @Armin 的建议(悬停与点击)或完全不同的回退将是关键。感谢你提出这个问题。
不太喜欢滚动……
我见过的优先级导航的最佳示例必须是这个网站
https://www.regionalaustraliabank.com.au/
复杂且视觉上有趣的桌面导航,但在移动设备上也很易用。
这真是太棒了。感谢分享。
可爱的設計。CSS3 动画的巧妙运用。
不错的帖子!感谢分享;)
我正在尝试类似的方法,但略有不同。如果你方便的话,请查看并提供反馈,请记住这只是一个正在进行中的项目,我尽量使用 CSS 来完成所有内容。
http://codepen.io/ricardpanades/pen/VjVRXG
干杯!
谢谢 Ricard,这是一个有趣的方法——很高兴看到它仅仅用 CSS 就实现了。
我唯一建议的是在第一次点击后显示所有子项,而不是让用户可能需要滚动两次。祝你好运!
请不要将导航栏放在轮播图中。比垂直项目列表更难使用。
我必须在这个上面贴一个“教条主义警示!”的标签。
挖掘它。看到我们停止思考的模式的新方法总是令人耳目一新(即使有大量数据表明我们应该继续思考它)。
我认为人们停止思考移动端导航设计的原因之一是,我们总是被告知**DRY DRY DRY**——但是对于多个断点严重修改一组标记非常糟糕。
我们不关心以 700kb 的 JS **开始**,但天哪,我们为导航生成 3 组标记。-__-
这是一个很棒的概念,虽然我不确定它是否足够直观,看看一些用户测试结果会很有趣。我很好奇是否有人错过了最初不可见的菜单项。
棘手的是,你的普通用户可能没有习惯滚动辅助导航,这仅仅是因为这是一项开创性的尝试。如果这很普遍,那将不是问题。我想汉堡菜单之所以受欢迎是因为每个人都知道该怎么做。实际上,现在我提到了这一点,你在 Goshen.edu 网站上的主导航栏的汉堡菜单略有不寻常,我第一次在我的手机上浏览该网站时,我以为它是徽标的一部分,一开始我没有注意到它,但现在是周一下午,哈哈!:)