网站上的菜单有很多不同的方法。一些菜单是持久的,始终可见并显示所有选项。其他菜单是隐藏的,需要打开才能查看选项。隐藏菜单揭示其菜单项的方式还有其他方法。一些菜单会弹出并覆盖内容,一些菜单会将内容推开,还有一些菜单会进行全屏处理。
无论采用哪种方法,它们都有其优缺点,适合的方法取决于使用情况。坦率地说,我通常喜欢弹出菜单。当然,并非所有情况下都适用。但是,当我在寻找一个占地面积小且易于访问的菜单时,弹出菜单是很难被击败的。
我不喜欢弹出菜单的地方是它们经常与页面内容发生冲突。弹出菜单充其量会遮挡内容,最糟糕的是会完全从 UI 中移除内容。
我尝试了另一种方法。它具有固定位置的持久性和可用性,以及隐藏菜单的节省空间的属性,只是不会将用户从当前页面内容中移除。
以下是我的实现方法。
切换
我们正在构建一个具有两种状态的菜单——打开和关闭——它在这两者之间切换。这就是 Checkbox Hack 发挥作用的地方。它很完美,因为复选框具有两种常见的交互状态——选中和未选中(还有 不确定)——可以用来触发这些状态。
复选框是隐藏的,并通过 CSS 放置在菜单图标下方,因此用户即使与它交互也永远不会看到它。选中复选框(或者,ahem,菜单图标)会显示菜单。取消选中它会隐藏它。就这么简单。我们甚至不需要 JavaScript 来做这件事!
当然,Checkbox Hack 不是唯一的实现方法,如果你想切换类来使用 JavaScript 打开和关闭菜单,这绝对没问题。
重要的是复选框在源代码中位于主要内容之前,因为我们将要最终编写以使它工作 的:checked
选择器需要使用兄弟选择器。如果这会给你带来布局问题,请使用 Grid 或 Flexbox 作为你的布局,因为它们与源顺序无关,就像我使用它的优势来 在 CSS 中计数 一样。
使用 appearance
CSS 属性,在添加菜单图标的伪元素之前,会将复选框的默认样式(由浏览器添加)去除,这样用户就不会看到复选框的正方形。
首先,基本标记
<input type="checkbox">
<div id="menu">
<!--menu options-->
</div>
<div id="page">
<!--main content-->
</div>
…以及 Checkbox Hack 和菜单图标的基本 CSS
/* Hide checkbox and reset styles */
input[type="checkbox"] {
appearance: initial; /* removes the square box */
border: 0; margin: 0; outline: none; /* removes default margin, border and outline */
width: 30px; height: 30px; /* sets the menu icon dimensions */
z-index: 1; /* makes sure it stacks on top */
}
/* Menu icon */
input::after {
content: "\2255";
display: block;
font: 25pt/30px "georgia";
text-indent: 10px;
width: 100%; height: 100%;
}
/* Page content container */
#page {
background: url("earbuds.jpg") #ebebeb center/cover;
width: 100%; height: 100%;
}
我也添加了#page
内容的样式,它将是一个全尺寸的背景图片。
过渡
单击菜单控件时会发生两件事。首先,菜单图标更改为 × 标记,表示可以单击它关闭菜单。所以,我们在复选框输入处于:checked
状态时选择复选框输入的::after
伪元素
input:checked::after {
content: "\00d7"; /* changes to × mark */
color: #ebebeb;
}
其次,主要内容(我们的“耳机”图像)会发生变换,显示下面的菜单。它会向右移动,旋转并缩小,其左上角会变成角度。这是为了使内容看起来像是被推回去了,就像一扇打开的门一样。
input:checked ~ #page {
clip-path: polygon(0 8%, 100% 0, 100% 100%, 0 92%);
transform: translateX(40%) rotateY(10deg) scale(0.8);
transform-origin: right center;
transition: all .3s linear;
}
我使用clip-path
来更改图像的角落。
由于我们在变换上应用了过渡,因此我们需要在#page
上有一个初始的clip-path
值,这样才能进行过渡。我们也会在#page
上添加一个过渡,因为它可以让它像打开一样平滑地关闭。
#page {
background: url("earbuds.jpeg") #ebebeb center/cover;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: all .3s linear;
width: 100%; height: 100%;
}
我们基本上完成了核心设计和代码。当复选框取消选中(通过单击 × 标记)时,耳机图像上的变换会自动撤消,并且它会自动回到最前面和中心。
少许 JavaScript
尽管我们已经得到了想要的东西,但还有一件事可以提升 UX:当单击(或点击)#page
元素时关闭菜单。这样,用户就不需要寻找甚至使用 × 标记来返回内容。
由于这仅仅是隐藏菜单的另一种方法,所以我们可以使用 JavaScript。如果由于某种原因 JavaScript 被禁用了呢?没什么大不了的。这只是一个增强功能,并不会阻止菜单在没有它的情况下工作。
document.querySelector("#page").addEventListener('click', (e, checkbox = document.querySelector('input')) => {
if (checkbox.checked) { checkbox.checked = false; e.stopPropagation(); }
});
这三行代码的作用是在#page
元素上添加一个点击事件处理程序,如果复选框处于:checked
状态,它会取消选中复选框,从而关闭菜单。
我们一直在查看一个为纵向/肖像设计制作的演示,但它在更大的横向屏幕尺寸上也能很好地工作,具体取决于我们正在处理的内容。
这只是对典型弹出菜单的一种方法或尝试。动画打开了大量的可能性,你可能还有几十个其他的想法。事实上,我很想听听(或者最好是看到)它们,所以请分享吧!
这是下一代移动菜单视图。
太棒了,太疯狂了,但总有一些属性是 VS 不识别的,即使它仍然完美地工作。而且我对此的一半都不理解
太棒了
为什么用 js 来隐藏菜单?
你可以简单地使用一个覆盖 #page 的定位标签,并在菜单不活动时使用 display none
这是下一代移动菜单。
很棒的循序渐进教程,Preethi。它非常易于理解和遵循。继续创作精彩的内容。