汉堡菜单按钮的实现

当用户点击菜单按钮,在弹出导航栏的同时,汉堡形状的按钮也会动画渐变成叉号。再次对其点击时,导航栏收回,按钮也恢复原样。关于汉堡菜单,虽然 GitHub 上已经有相关的库 hamburgers,但因为我使用的 nuxt 框架采用的是 rem 布局,对于 px 到 rem 的转换让我实在头疼。再三思量之下,还是决定自己手动模仿一个出来。具体实现效果如下动图。

hambuger

一、设计思路

至于将三横杠动态渐变成叉号的具体过程,每个人都有自己的奇思妙想,不必拘泥。这里简要说明上述动画的设计思路:

  1. 将顶部横杠顺时针旋转 90 度,同时将其向下移动一段距离,使得其和中间横杠构成完美对称的➕。
  2. 将底部横杠向上移动一段距离,使其与中间横杠重合。
  3. 中间横杠逐渐向中心消失。
  4. 整体再旋转一定角度,即让➕转动到✖。

以上四个步骤都是同时发生,并且同时结束。对于这三条横杠,有人采用一个 div 加上其::before::after两个伪元素通过定位来实现,有人则采用 div 里嵌套三个 span。前者方便易懂,后者更为灵活,所以我选择在 ul 里放 3 个 li。

之前在一篇文章看到在采用 transition 监听关于位置变化的属性时,采用 translate 来改变位置会比定位的性能更好。但这篇文章目前找不到在哪里了,以后若是有缘碰到再放在这里补充。所以这里都是通过 transform 属性来改变元素的具体位置。

二、代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>汉堡菜单</title>
<style>
.menu {
width: 52px;
height: 30px;
transition: all 5s;
}
.menu li {
width: 52px;
height: 3.5px;
background-color: red;
transition: all 5s;
}
.menu .m {
transform: translateY(8.5px);
}
.menu .b {
transform: translateY(16.5px);
}
.menu:hover .t {
transform: translateY(12px) rotate(90deg);
}
.menu:hover .m {
transform: translateY(8.5px) scaleX(0);
}
.menu:hover .b {
transform: translateY(4.75px);
}
.menu:hover {
transform: rotate(225deg);
}
</style>
</head>
<body>
<ul class="menu">
<li class="t"></li>
<li class="m"></li>
<li class="b"></li>
</ul>
</body>
</html>

三、transform 补充

关于 transform 属性的使用,这里要补充几点。拿中间横杠举例,它的初始位置状态是transform: translateY(8.5px),它的长度要从两边到中间递减,所以可以采用 transform 的另一个属性 scaleX() 来实现。但不可以直接把状态改成transform: scaleX(0),因为这相当于重写属性,从而导致之前 translateY(8.5px) 属性值丢失。另外,transform: translateY(8.5px) scaleX(0)的两个属性值也不能颠倒。