汉堡菜单按钮:当用户点击菜单按钮,在弹出导航栏的同时,汉堡形状的按钮也会动画渐变成叉号。再次对其点击时,导航栏收回,按钮也恢复原样。
关于汉堡菜单,虽然 GitHub 上已经有相关的库 hamburgers,但因为我使用的 nuxt 框架采用的是rem布局,对于px到rem的转换让我实在头疼。再三思量之下,还是决定自己手动模仿一个出来。具体实现效果如下动图。
一、设计思路
至于将三横杠动态渐变成叉号的具体过程,每个人都有自己的奇思妙想,不必拘泥。这里简要说明上述动画的设计思路:
- 将顶部横杠顺时针旋转90度,同时将其向下移动一段距离,使得其和中间横杠构成完美对称的➕。
- 将底部横杠向上移动一段距离,使其与中间横杠重合。
- 中间横杠逐渐向中心消失。
- 整体再旋转一定角度,即让➕转动到✖。
以上四个步骤都是同时发生,并且同时结束。对于这三条横杠,有人采用一个div加上其::before
和::after
两个伪元素通过定位来实现,有人则采用div里嵌套三个span。前者方便易懂,后者更为灵活,所以我选择在ul里放3个li。
之前在一篇文章看到在采用transition监听关于位置变化的属性时,采用translate来改变位置会比定位的性能更好。但这篇文章目前找不到在哪里了,以后若是有缘碰到再放在这里补充。所以这里都是通过transform属性来改变元素的具体位置。
二、代码实现
<!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)
的两个属性值也不能颠倒。