汉堡按钮(Hamburger menu)经常使用于移动端网站 展开/收起 导航,若是在点击按钮时再增长一些过渡动画则会显得更加生动有趣。今天咱们就快速实现一个带有过渡动画的汉堡按钮。效果如图:css
html 结构很简单,两个 div
足以:html
<div class="menu"> <div class="hamburger"></div> </div>
div.menu
表明按钮,div.hamburger
表明按钮中的线段。可是一个 div
如何显示 3 条线段?有同窗应该想到了,能够用 ::before
、::after
伪元素。git
为了让代码更简洁,选择使用 Sass 书写样式。github
首先咱们须要定义一些变量,减小重复的参数。写样式的时候也能够像写组件那样去提炼配置,经过配置去修改、扩展。好比,线段的尺寸、位置均可以经过按钮尺寸 $menu-size
计算获得,这样一旦咱们须要修改按钮尺寸就只须要修改 $menu-size
这一个参数就好了。sass
变量:动画
$menu-size: 300px; // 按钮尺寸 $line-width: $menu-size * 0.66; // 线段宽度 $line-height: $menu-size * 0.1; // 线段高度 $line-spacing: $menu-size * 0.22; // 线段间距 $line-color: #f44336; // 线段颜色
按钮样式:网站
常规操做,没啥好讲的...spa
.menu { // 水平、垂直居中 position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); // 宽高 width: $menu-size; height: $menu-size; // 其余 cursor: pointer; background-color: rgba(255, 255, 255, 0.5); border-radius: 6%; }
线段样式:3d
.hamburger { // 水平、垂直居中 top: 50%; left: 50%; transform: translate(-50%, -50%); // 线段样式 &, &::before, &::after { content: ""; position: absolute; width: $line-width; height: $line-height; background: $line-color; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); // 过渡时间 transition: 0.5s; } // 线段1位置 &::before { top: -$line-spacing; } // 线段3位置 &::after { top: $line-spacing; } }
注意点:code
- 使用
transition
设置动画的过渡时间::before
、::after
伪元素是相对于div.hamburger
进行绝对定位(绝对定位的定义是:相对于最近的非static
定位的祖先元素的进行偏移。而不是 不少同窗印象中的相对于position:relative
的祖先元素进行定位)
激活状态:
当点击按钮后经过 Javascript 给 div.menu
添加 active
的 class,表示按钮进入激活状态:
.menu.active { .hamburger { // 隐藏线段2 background-color: transparent; box-shadow: none; // 线段1 旋转定位 &::before { top: 0; transform: rotate(45deg); } // 线段3 旋转定位 &::after { top: 0; transform: rotate(135deg); } } }
注意点:
- 隐藏线段 2 不能直接
display:none
或者visibility: hidden
,这样会致使使用伪元素实现的线段 一、3 都被隐藏,而是经过将背景色设置为透明实现- 给
::before
,::after
设置top: 0
至关于把线段 一、3 移到按钮中间,而后再进行旋转- 设置其余角度也能够达到最后变成 x 的效果,好比:
&::after {transform: rotate(-45deg)}
,只不过中间变换的过程会有所区别- 对中间变换过程有疑惑的同窗建议将
transition
时间调长,仔细观察
最后,监听按钮的点击事件,toggle 激活状态:
const menu = document.querySelector(".menu"); menu.addEventListener("click", () => { menu.classList.toggle("active"); });
好了,大功告成!
本文 Demo 参考:Codepen Trick by Day (2020-07-07) Transforming Hamburger Menu
天天一个小技巧(Tricks by Day),量变引发质变,但愿你和我一块儿天天多学一点,让技术有趣一点。全部示例将会汇总到个人 tricks-by-day github 项目中,欢迎你们莅临指导 😊