前几天晚上我突然有了一个很蠢的小想法,然后我就把它写成了代码(就是这样)。您知道那些用来表示导航的小图标吗?我们这里称它们为 三线菜单 图标,但它们也被称为 Navicon(很聪明)或汉堡包(很蠢)。这个图标的重点是它看起来像一个小菜单,所以希望很明显,您点击它可以显示一个真正的菜单。但是,如果这个图标根本不是一个图标,而是一个缩小的实际菜单呢?
概念
是的,它有点俗气。

不过这个技巧非常简单。它主要依赖于 CSS transform 和 transition,以及其他一些基本知识。
过程本质上是
- 首先设计全尺寸视图
- 使用 transform: scale(0.X); 将整个内容缩小到图标大小
- 使用
opacity: 0移除不必要的部分 - 当处于图标大小的时候,只对整个内容的点击做出反应。
- 当点击时,切换到
transform: scale(1),将隐藏的部分设置为opacity: 1,并恢复正常的点击功能。
这是设计部分

更改状态
您可以通过多种方式更改菜单的“状态”(展开或折叠)。也许可以使用 复选框技巧 或者使用 jQuery 很容易地实现。
$(".main-nav").on("click", function() {
$(this).toggleClass("open");
return false;
});
我们在这里做的只是更改一个类,这 绝对是最佳做法。
CSS
在处理状态时,我特别喜欢 Sass,因为您可以在同一个块中嵌套状态。
.main-nav {
/* Animate the state change */
transition: 0.3s ease;
transform:
/* Make mini */
scale(0.1)
/* Hot performance 10x hack */
translateZ(0);
/* The open state */
&.open {
transform: scale(1.0);
}
}
处理点击
点击的事情有点奇怪。我们需要确保
- 点击图标版本只需打开菜单
- 在打开状态下点击菜单项可以正常工作
- 有一种方法可以关闭它
我们已经有了 jQuery,它可以在您点击整个元素的任何位置时切换类。可以保持原样。我们只需要确保,如果您碰巧点击了微型图标内部的那些细小的线条之一,您实际上不会跳转到该链接。
所有这些链接都在一个 <ul> 中,因此处理此问题的一种方法是使用 CSS 使整个内容默认情况下不可点击(最小化),但在打开状态下可点击。
.main-nav {
ul {
pointer-events: none;
}
&.open {
ul {
pointer-events: auto;
}
}
}
虽然 pointer-events 很棒,但 支持方面存在明显的差距,IE 10 就是如此(不过 IE 11 支持它)。您可能希望使用一个额外的 <div>,在默认(最小化)状态下使用它来覆盖整个内容,并在打开状态下将其移除。
关闭它
我们处理关闭的方式是添加一个关闭按钮
<button class="close-button">
<b class="visually-hidden">Close</b>
<span aria-hidden="true">
×
</span>
</button>
我们希望在那里使用 × 字符作为图标。但如果读取(或者如果它有意义的话,那就是“乘法”),它没有任何意义。因此,我们隐藏了它不被读取,并包含一个更易读的单词,该单词是视觉上隐藏的(使用定位将其踢出页面)。使用图标的标准程序。
在我们的简单示例中,我们甚至不需要将事件处理程序直接绑定到此按钮,因为我们已经有一个附加到整个父元素上的事件处理程序,它可以切换打开状态。如果您点击此按钮,该事件将冒泡并触发该事件并完成工作。这可能很奇怪,因此请随意调整并直接绑定到元素。
语义?
虽然这个 <button> 并没有让我感到厌恶,但我们可以就它进行无休止的辩论。(示例对话)。在没有启用 JS 的情况下,它毫无意义,那么我们应该使用 JS 插入它吗?我们是否应该将其设为带有返回页面顶部的 href 的锚链接?<button> 仍然是正确的元素吗?
渐进增强?
虽然我们只是在这里玩乐,但我们可能会考虑通过渐进增强来解决这个问题。也就是说,从一个仅作为标记完全可用的菜单开始。然后,随着支持的可用性,提升所有花哨的功能。
幸运的是,我们的标记已经大部分处于良好的状态。我认为 <button> 是我们关闭按钮的正确元素,因为没有“有意义的 href”,但它应该使用 JS 插入,因为它只有在使用 JS 时才有功能。非常简单,可能看起来像这样
$('<button class="close-button">\
<b class="visually-hidden">Close</b>\
<span aria-hidden="true">\
×\
</span>\
</button>').appendTo(".main-nav");
另一个问题是,我们以这样一种方式处理 CSS,即默认状态是菜单关闭。并且该“关闭”状态本质上依赖于 CSS 变换来缩小它。如果不支持 CSS 变换,菜单将显示为打开状态,覆盖内容并且无法关闭(糟糕)。如果我们的菜单没有覆盖内容,我们可能没问题,但由于它确实覆盖了内容,因此最好仅在浏览器支持我们的花哨 CSS 需求时才应用我们的花哨样式。
有无数种方法可以解决这个问题,但一种相当简单且标准的方法是通过 Modernizr 检测相关技术的支持情况。如果我们需要的功能存在,<html> 元素上将有一个类名告诉我们这一点,我们可以使用它来应用花哨的功能。
.main-nav {
/* Default, visible, accessible styling */
}
.csstransforms .main-nav {
/* Bring the fancy */
}
IE 8 不支持 CSS 变换,因此

我再次将一个愚蠢的小演示变成了一个课程。这是最终的解决方案
查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的 扩展为实际菜单的线形菜单图标
其他想法?
也许这个想法本身很俗气,但我确实喜欢您点击的内容成为显示内容的一部分的想法。这有点像动画如何用于使操作更清晰,在这些动画期间拥有一个焦点也可以提供帮助。例如
查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的 owgLF
你太疯狂了……哦,我的天,我太喜欢这个想法了!
这太酷了!CSS 过渡就像魔法一样。
我挺喜欢这个想法的基本前提,但我不喜欢导航中项目的数量会影响关闭图标的整体外观。我认为约定俗成的做法是使用三条线,虽然可以偏离这个约定,但使用 5 或 7 条线看起来有点荒谬。
您知道我们在最小化版本中如何隐藏各种元素以使其看起来更像图标。您可以隐藏超过 4 个的任何菜单项,例如
:nth-child(n+4),请参阅食谱另一种为响应式设计创建可折叠导航菜单的方法。令人印象深刻!
非常有帮助:) 谢谢:)
嘿,Chris,
很棒的概念,执行得非常酷:)
喜欢这个。
我喜欢它,它有一些过渡效果,与如何执行一些基本的展开非常相关。做得好!!
嘿,Chris,我非常喜欢你在这里提出的概念。将图标扩展为交互式 UI 元素的想法可以扩展到远远超出菜单图标的范围!感谢你的灵感(对于这篇文章和之前的所有文章)!
祝您假期快乐,先生。
很棒。
太棒了!!!我知道我今晚要做什么了!
http://codepen.io/AtomicNoggin/pen/xgHpn
这是一个使用标签作为关闭按钮和隐藏复选框来切换菜单的版本,无需使用任何额外的脚本或插入的标签。
我们称它们为……芝士汉堡!
我爱这个概念。
非常有趣,不错的帖子!谢谢!
很棒的帖子,Chris!
我从这里获得灵感,使其更具通用性。仍然需要一些改进,但我希望获得大家的想法和意见。
http://codepen.io/nickspiel/pen/ohCKF
那真是太棒了,Nick!
那真是太棒了,Nick!
喜欢它,有点让我想起 Path 发布时的新菜单概念。在响应式网站上实现这一点应该很容易,这令人兴奋。
我不知道为什么,我知道这听起来很蠢,但对我来说,它看起来更自然:)
一点也不蠢。事实上,这是 UX 工程师试图在其软件解决方案中实现的动画类型。您越接近模拟现实生活中的交互,它就越熟悉,也越自然。
毕竟,您浏览器上的选项卡仍然看起来像一堆纸质文件夹选项卡。
Chris,我认为你的“愚蠢的小演示”实际上是一个非常棒的概念。
我同意Alan Cece的观点,也许将其限制在一致的三四个项目可能是一个好主意。
我还发现,当我更改您笔中的 CSS 以便文本在图标状态下实际上可见(尽管在那个尺寸下不可读)时,我更喜欢它。图标和展开菜单之间的连接变得更加清晰。
一个很棒的想法,过渡效果很棒。我非常喜欢这种类型的过渡,有点像这个
http://media.smashingmagazine.com/wp-content/uploads/2013/10/Stateful-toggle.gif
来自这篇文章。
但是,我不确定汉堡包/导航图标是否已被广泛认可,可以单独用作图标。关闭符号或搜索放大镜在计算机拥有 GUI 以来就一直存在,并且几乎是每个操作系统的一部分。
这比较新,所以我更愿意将其与“菜单”或类似的标签一起使用。
非常棒的想法!
也许我会在即将到来的项目中坚持使用它。
感谢分享!
非常棒的想法!
非常棒的概念。
感谢分享!
正是像你这样的人不断激励我去尝试新事物。这太独特,太棒了,我从未见过类似的东西。
非常鼓舞人心。感谢分享。
我非常喜欢这个想法,Chris。它非常有创意。
这确实让我想知道还有哪些场景需要用标记和 CSS 绘制某些东西并将其缩放到图标的大小。例如,典型的语音气泡“评论”图标可以是样式化文本区域的缩小版本,当您点击它时,该文本区域会变得足够大以供使用。
很酷的项目!
您真的需要点击吗?您真的需要 JavaScript 吗?到目前为止,仅在 Chrome + Firefox 中测试过。如果有人愿意,请在任何地方进行测试:) http://codepen.io/anon/pen/GuCHk
(当然是在桌面上。在移动设备上仍然需要点击[触摸]。)
我喜欢这个版本。用户的工作量更少。
我认为“汉堡包”也很蠢!喜欢这个。谢谢,Chris!
我期待着浏览器能够处理这种情况的那一天,并且在过渡期间不会导致页面上的所有其他文本和线条更改权重或闪烁。这毫无疑问很棒,但我还没有见过任何动画如此出色以至于胜过该死的闪烁。是否有任何硬件执行类似的技巧可以阻止这种情况发生?太接近了!
我真的很喜欢这个想法,我自己也尝试过,代码与您展示的一样,但它不起作用。您能将完整代码发送给我吗?非常感谢。
我赞同。我一直试图让它工作,但我太新手了,无法成功。
我实际上非常喜欢这个概念,也许它可以在移动布局上更好地工作。我喜欢所有元素都包含在内,并且仅使用过渡的方式。
想法很酷,我认为这将成为未来的趋势。
只有在使用内联样式时才有效。当我将 CSS 代码放在一个单独的文件中并链接到 HTML 文件时,菜单框无法正常显示。我花了大约一个小时,但找不到原因?
哇。真是神奇……让我开始研发……:)
非常喜欢这个想法,Chris。非常有创意。
这确实让我想知道还有哪些场景需要用标记和 CSS 绘制某些东西并将其缩放到图标的大小。例如,典型的语音气泡“评论”图标可以是样式化文本区域的缩小版本,当您点击它时,该文本区域会变得足够大以供使用。
您好,
我喜欢它的简洁和易用性,但不知何故,我无法在 Codepen 之外使用 Chrome 33+ 使其工作(好吧,我确实是个新手)。有人愿意详细说明一下吗?
将所有内容放在一个 HTML 文件中,无法工作
所有内容放在单独的文件中(CSS、JS、HTML)也无法工作
使用了 jQuery 2.1.0
谢谢,rene