CSS & JS Effect – Hamburger Menu
效果
参考:
Youtube – Responsive Navigation Menu Bar + Hamburger Menu Toggle - Only with CSS
Youtube – Making an animated hamburger button and a challenge to you!
Youtube – JavaScript - How to Create a Responsive Hamburger Menu with HTML, CSS, & JavaScript
做法
一条一条的 bar 是 div / span 做的.
点击的时候, 中间的 bar 消失, 上下的 bar rotate 就形成了 X
HTML
<div class="nav"> <input class="hamburger-toggle" type="checkbox" /> <span class="hamburger"></span> </div>
checkbox 用来做 toggle, 其实用 JS 做会比较容易. checkbox 的 size 不容易控制, 又要搞定位什么的, 很不直观.
hamburger bar 虽然有三条, 但上下 2 条是用 ::before ::after 搞出来的. 其实要用 3 个 span 也是 ok 的, 甚至更直观.
CSS Style
3 bar style
.hamburger, .hamburger::before, .hamburger::after { background-color: black; width: 2rem; height: 0.25rem; display: inline-block; transition-property: transform top opacity; transition-duration: 0.4s; }
3 条 bar 一起画.
transition 是等下 toggle 时 rotate 和 opacity 的过渡效果.
top, bottom bar style
.hamburger { position: relative; &::before, &::after { content: ""; position: absolute; } &::before { top: -0.5rem; } &::after { top: 0.5rem; } }
这里要注意, 3 条 bar 并不是 sibling. 它是 parent child
但是眼睛看上去应该要是 before, hamburger, after sibling才对.
所以就需要用到绝对定位. 感觉很不直观...
通过绝对定位, 它们就重叠了, 然后 before top -0.5rem 往上, after top 0.5rem 往下, 最终就形成 3 条 bar 了.
checkbox style
.nav { position: relative; .hamburger-toggle { position: absolute; top: 0px; left: 0px; width: 2rem; height: 100%; z-index: 1; opacity: 0; cursor: pointer; } }
它也是绝对定位, 因为要和 3 条 bar 重叠, 这样才点击的到, 用 opacity 让它消失 (看不见但是点击的到)
toggle checked style
.hamburger-toggle { &:checked ~ .hamburger { background-color: transparent; &::before { transform: rotate(45deg); top: 0; } &::after { transform: rotate(-45deg); top: 0; } } }
checked 时让中间的 bar, 也就是 .hamburger background-color transparent 消失. 这里不可以用 opacity 哦.
因为 opacity 会同时让它的 child (before, after) 一起消失, 这不是想要的.
before 和 after 就 rotate 45°, 一个往上, 一个往下, 默认的 rotate origin (轴心) 是 center 所以必须加上 top 0 调回正中间.
如果没有 top: 0 效果是下面这样.
红色是原来的位置, 黑色是 rotate 以后的位置. 当把 2 个 set 成 top:0, 上面的 bar 往下移, 下面的往上移, 2 个 bar 在中间交会就形成了 X.
注: rotate 以后 width 就比原本的短了, 所以左边会有一点点偏移, 但是看不太出来, 所以不用理会.
完整代码
HTML
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<div class="nav"> <input class="hamburger-toggle" type="checkbox" /> <span class="hamburger"></span> </div>
Sass
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
.nav { position: relative; .hamburger-toggle { position: absolute; top: 0px; left: 0px; width: 2rem; height: 100%; z-index: 1; opacity: 0; cursor: pointer; &:checked ~ .hamburger { background-color: transparent; &::before { transform: rotate(45deg); top: 0; } &::after { transform: rotate(-45deg); top: 0; } } } .hamburger, .hamburger::before, .hamburger::after { background-color: black; width: 2rem; height: 0.25rem; display: inline-block; transition-property: transform top opacity; transition-duration: 0.4s; } .hamburger { position: relative; &::before, &::after { content: ""; position: absolute; } &::before { top: -0.5rem; } &::after { top: 0.5rem; } } }
直观版本
如果不喜欢搞一堆的定位, before after, 也可以用最简单的 way.
HTML
<button class="menu-btn"> <span class="top-bar"></span> <span class="center-bar"></span> <span class="bottom-bar"></span> </button>
CSS Style
.menu-btn { --bar-gap: 0.75rem; width: 100px; height: 100px; display: flex; flex-direction: column; justify-content: center; gap: var(--bar-gap); .top-bar, .center-bar, .bottom-bar { background-color: currentColor; height: 1rem; width: 100%; border-radius: 999px; transition-property: transform opacity; transition-duration: 0.4s; } &.opened { .center-bar { opacity: 0; } .top-bar { transform: translateY(calc(var(--bar-gap) + 100%)) rotate(45deg); } .bottom-bar { transform: translateY(calc(-1 * (var(--bar-gap) + 100%))) rotate(-45deg); } } }
需要留意它的 transform 还加上了 translateY 桥位置.
JS
document.querySelector('.menu-btn').addEventListener('click', event => { event.currentTarget.classList.toggle('opened'); });
相关文章
- RHEL & Ubuntu & JDK Install Root Certificates
- Linux 时间&时区
- 玩转Kafka—Spring&Go整合Kafka
- 读JS高级API笔记_(DOM&&DOM2&&DOM3)哎呀——园龄才9个月啊
- (数据科学学习手札24)逻辑回归分类器原理详解&Python与R实现
- oc懒加载 & swift lazy
- 《软件建模与设计: UML、用例、模式和软件体系结构》一一第3章Software Modeling & Design: UML, Use Cases, Patterns, & Software Architectures
- js 收藏&设置为首页
- 【斗鱼直播源】浏览器抓取真实直播源地址(纯前端JS & PHP解析源码)
- JS修改当前控件样式&为控件追加事件
- rsa && sha1 js code
- jQ&js给label
- js解析url参数如http://www.taobao.com/index.php?key0=21&key1=你哈&(获取key0和key1的值)
- JS魔法堂:不完全国际化&本地化手册 之 实战篇
- JS魔法堂:再识Bitwise Operation & Bitwise Shift
- JS魔法堂:IE5~9的Drag&Drop API
- 2022&2023华为OD机试 - 压缩报文还原(JS)
- 【分布式计算】DFS && BigTable
- hdu 4122 Alice's mooncake shop (线段树)
- Unity 生成二维码 & 融合图片
- 有奖试读&征文--当青春遇上互联网,是否能点燃你的创业梦
- IDC&Gartner :2016年PC市场将迎来一缕曙光
- Dynamices CRM JS 类库 神器 XrmServiceToolkit - A Microsoft Dynamics CRM 2011 & CRM 2013 JavaScript Library
- GAMES202作业0-环境搭建过程&解决遇到的问题