汉堡菜单
by Jared Tong
汤杰(Jared Tong)
开发人员在编写汉堡菜单时犯的错误 (The mistake developers make when coding a hamburger menu)
What do The New York Times’ developers get wrong about the hamburger menu, and what do Disney’s and Wikipedia’s get right?
《纽约时报》的开发人员在汉堡菜单上犯了什么错误,迪士尼和维基百科的做错了什么?
As far as I know, I’ve found only one way to style the hamburger menu’s open state that supports iOS Safari. (Presumably, you want a mobile view to work on iPhone!)
据我所知,我发现只有一种方式可以设置支持iOS Safari的汉堡菜单的打开状态。 (想必您希望在iPhone上使用移动视图!)
It’s all about how the hamburger menu is positioned.
这与汉堡菜单的放置方式有关。
许多汉堡菜单的问题 (The Problem with Many Hamburger Menus)
If your hamburger menu has no need for scroll… Congratulations! The CSS solution you’re thinking of now will probably work just fine: position the sidebar absolutely out of and into the view-port when the user clicks on the menu icon.
如果您的汉堡菜单不需要滚动……恭喜! 您现在正在考虑CSS解决方案可能会很好地起作用:当用户单击菜单图标时,将侧边栏绝对移出视口并放入视口中。
If your menu has more items than the view-port can display at once, this is what happens when your hamburger menu is positioned absolutely:
如果菜单中的项目多于视图一次显示的数量,则当绝对放置汉堡菜单时会发生以下情况:
If you don’t want to watch the video, I’ll try and describe it in words.
如果您不想观看视频,我将尝试用文字描述。
Scrolling within the
position: absolute
menu is unpleasant: it does not scroll smoothly, and when it reaches the end of scroll, it does not bounce in that satisfying, patented rubber-band way. Try the hamburger menus on New York Times, or Pitchfork.在以下
position: absolute
滚动position: absolute
菜单令人不快:滚动不流畅,到达滚动末尾时,不会以令人满意的专利橡皮筋弹跳。 试试《纽约时报》或干草叉上的汉堡菜单。If you over-scroll in the hamburger menu, iOS Safari will scroll the body instead. Try the sidebar on Viki.
如果在汉堡菜单中过度滚动,iOS Safari将改为滚动身体。 在Viki上尝试侧边栏。
An alternative is to use
position:fixed
and-webkit-overflow-scrolling: touch
on the sidebar. Even then, if you tap beyond the menu, like scrolling on the sliver of main content exposed beside the sidebar, you will lose the ability to scroll within the menu. Try the hamburger menu on Grab.另一种方法是使用
position:fixed
和-webkit-overflow-scrolling: touch
侧边栏。 即使那样,如果您点击菜单之外的内容,例如滚动显示在侧边栏旁边的主要内容,也将失去在菜单中滚动的能力。 试试Grab上的汉堡菜单。
Notice how sometimes iOS scrolls the menu, sometimes it scrolls the body behind the menu? Frustrating!
请注意,iOS有时如何滚动菜单,有时它如何滚动菜单后面的主体? 令人沮丧!
And FWIW, you can break the scroll on Apple.com too. An easy way to trigger the scroll on the hamburger menu is to use your phone horizontally.
和FWIW,您也可以在Apple.com上中断滚动。 触发汉堡菜单上滚动的一种简单方法是水平使用手机。
解决方案 (The Solution)
Basically, the key thing you must remember about the Menu’s final, open state is this: instead of positioning the menu absolutely, it will be the main content that is positioned once the sidebar is opened. In other words, instead of positioning the menu, position everything else!
基本上,关于菜单的最终打开状态,您必须记住的关键是:绝对不放置菜单,而是在打开侧栏后定位的主要内容。 换句话说, 不要放置菜单 , 而是放置其他所有内容 !
Here is that in code, alongside explanatory comments:
这是代码中的内容,以及解释性注释:
<html><head></head><body> <div class="sidebar">Hamburger menu links go here</div> <div class="main-content"><button class="hamburger-menu-icon" onClick="toggleSidebar()">?</button></div></body></html>
/* Arbitrary CSS variable values for explanatory purposes */:root { --sidebar-width: 100px; --sidebar-bg-colour: blue;}.sidebar { display: none; position: relative; width: var(--sidebar-width);}@media (max-width: 767px) { html.sidebar-is-open .sidebar { display: block; /* The sidebar is just rendered in default position, as it appears in the document flow */ } html.sidebar-is-open .main-content { position: fixed; /* It is the main content that is positioned. This is the crux of the implementation. The rest is all sugar. Cons: the body will scroll to the top, losing your user's scroll position */ /* prevents resizing from its original full-screen width */ bottom: 0; left: 0; right: 0; top: 0; width: 100%; overflow: hidden; } /* Optional enhancement: make the over-scroll on iPhone the same color as the sidebar */ html.sidebar-is-open body { background-color: var(--sidebar-bg-colour); } .sidebar { background-color: var(--sidebar-bg-colour); }}
const documentElement = document.querySelector("html");const contentElement = document.querySelector(".main-content");const sidebarElement = document.querySelector(".sidebar");const sidebarIsOpen = () => documentElement.classList.contains("sidebar-is-open");const openSidebar = () => { /* How you trigger the change is up to you */ documentElement.classList.add("sidebar-is-open");};const closeSidebar = () => { documentElement.classList.remove("sidebar-is-open");};const toggleSidebar = () => { sidebarIsOpen() ? closeSidebar() : openSidebar();};
结论 (Conclusion)
So far I’ve found two big players who get it right: Wikipedia and Disney USA.
到目前为止,我发现有两个正确的大公司: Wikipedia和Disney USA 。
Try their hamburger menus on iOS and see what a great experience the scrolling is!
在iOS上尝试他们的汉堡包菜单,看看滚动带来的绝佳体验!
Hopefully you can spread the word, and fix hamburger menus from now on.
希望您能从现在开始传播这个词,并修复汉堡包菜单。
If you’re more of a beginner, you can find an explanation of what a hamburger menu is and how to build a hamburger menu from scratch on my blog.
如果您是初学者,可以在我的博客上找到有关什么是汉堡包菜单以及如何从头开始构建汉堡包菜单的说明 。
翻译自: https://www.freecodecamp.org/news/the-mistake-developers-make-when-coding-a-hamburger-menu-f46c7a3ff956/
汉堡菜单