CSS实现Menu Toggle移动菜单切换按钮(打开/关闭)

移动菜单一般都有一个开关按钮,可以点击按钮打开或关闭菜单,本文将介绍一个CSS实现的Menu Toggle移动菜单切换按钮(打开/关闭)。

demodownload

HTML

<button class="btn-toggle" id="menu-toggle">
  <div class="line"></div>
  <div class="line"></div>
  <div class="line"></div>
</button>

HTML代码很简单,盒子是一个button标签,该标签class值是btn-toggleid值是menu-toggle

button标签内有3个div,它们的class值都是line

Javascript

本实例有少量的JS代码,其作用是监听按钮的点击动作,打开或关闭菜单。

const btn = document.getElementById("menu-toggle");
const lines = btn.querySelectorAll(".line");
const cls = { open: "open", close: "close" };
let btnClass = cls.open;

btn.addEventListener("click", () => {
  if (btn.classList.contains(cls.open)) {
    btn.classList.remove(btnClass);
    btnClass = cls.close;
  } else if (btn.classList.contains(cls.close)) {
    btn.classList.remove(btnClass);
    btnClass = cls.open;
  }

  void btn.offsetWidth;
  btn.classList.add(btnClass);
});

CSS

本实例CSS代码主要是实现了按钮样式的设计,以及当按钮的点击动作发生后,按钮状态的变化,打开/关闭过渡效果的设计。

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: snow;
}

.btn-toggle {
  position: relative;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  padding: 12px;
  background-color: transparent;
  border-color: transparent;
  outline: none;
  transform: translateZ(0);
  transition: transform 0.1s ease-out;
}
.btn-toggle:active {
  transform: translateY(4px);
}
.btn-toggle:focus .line:after {
  background-color: black;
}

.line {
  display: block;
  width: 60px;
  padding: 3.75px;
}
.line:after {
  content: "";
  display: block;
  width: 100%;
  height: 7.5px;
  background-color: dimgray;
  border-radius: 2px;
  transform: translateZ(0) rotate(0);
  transition: background-color 0.2s ease-out;
}
.open .line:nth-child(1) {
  -webkit-animation: jump-1 0.9s forwards ease;
          animation: jump-1 0.9s forwards ease;
}
.open .line:nth-child(1):after {
  -webkit-animation: line-1 0.9s forwards ease-in-out;
          animation: line-1 0.9s forwards ease-in-out;
}
.open .line:nth-child(2) {
  -webkit-animation: jump-2 0.9s forwards ease;
          animation: jump-2 0.9s forwards ease;
}
.open .line:nth-child(2):after {
  -webkit-animation: line-2 0.9s forwards ease-in-out;
          animation: line-2 0.9s forwards ease-in-out;
}
.close .line:nth-child(1) {
  animation: jump-1 0.9s reverse ease;
}
.close .line:nth-child(1):after {
  animation: line-1 0.9s reverse ease-in-out;
}
.close .line:nth-child(2) {
  animation: jump-2 0.9s reverse ease;
}
.close .line:nth-child(2):after {
  animation: line-2 0.9s reverse ease-in-out;
}
.open .line:nth-child(3), .close .line:nth-child(3) {
  -webkit-animation: jump-3 0.9s forwards ease-out;
          animation: jump-3 0.9s forwards ease-out;
}

@-webkit-keyframes line-1 {
  10% {
    transform: translateZ(0) rotate(0);
  }
  80% {
    transform: translateZ(0) rotate(395deg);
  }
  90%, 100% {
    transform: translateZ(0) rotate(405deg);
  }
}

@keyframes line-1 {
  10% {
    transform: translateZ(0) rotate(0);
  }
  80% {
    transform: translateZ(0) rotate(395deg);
  }
  90%, 100% {
    transform: translateZ(0) rotate(405deg);
  }
}
@-webkit-keyframes line-2 {
  10% {
    transform: translateZ(0) rotate(0);
  }
  20% {
    transform: translateZ(0) rotate(10deg);
  }
  90%, 100% {
    transform: translateZ(0) rotate(-405deg);
  }
}
@keyframes line-2 {
  10% {
    transform: translateZ(0) rotate(0);
  }
  20% {
    transform: translateZ(0) rotate(10deg);
  }
  90%, 100% {
    transform: translateZ(0) rotate(-405deg);
  }
}
@-webkit-keyframes jump-1 {
  10% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-90px);
  }
  90%, 100% {
    transform: translateY(-7.5px);
  }
}
@keyframes jump-1 {
  10% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-90px);
  }
  90%, 100% {
    transform: translateY(-7.5px);
  }
}
@-webkit-keyframes jump-2 {
  10% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-75px);
  }
  85%, 100% {
    transform: translateY(-22.5px);
  }
}
@keyframes jump-2 {
  10% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-75px);
  }
  85%, 100% {
    transform: translateY(-22.5px);
  }
}
@-webkit-keyframes jump-3 {
  10% {
    transform: translateY(-7.5px) rotate(15deg);
  }
  30% {
    transform: translateY(-30px) rotate(-10deg);
  }
  50% {
    transform: translateY(7.5px) rotate(5deg);
  }
  80% {
    transform: translateY(0);
  }
}
@keyframes jump-3 {
  10% {
    transform: translateY(-7.5px) rotate(15deg);
  }
  30% {
    transform: translateY(-30px) rotate(-10deg);
  }
  50% {
    transform: translateY(7.5px) rotate(5deg);
  }
  80% {
    transform: translateY(0);
  }
}
@-webkit-keyframes glow {
  50% {
    box-shadow: rgba(131, 131, 131, 0.4) 0 0 2px 2px;
  }
}
@keyframes glow {
  50% {
    box-shadow: rgba(131, 131, 131, 0.4) 0 0 2px 2px;
  }
}

.btn-toggle 定义按钮盒子模型样式:位置、背景、边框等。

 

.line 定义横线样式。

 

 

.open .line.close .line 定义按钮(开/关)横线过渡动画。

nth-child(n) n值为1-3,分别代表第1到第3条横线。

下面是动画参数的解释:

animation: jump-1 0.9s forwards ease;  jump-1是动画名称,它由@-webkit-keyframes jump-1 {}来定义,0.9s是动画时间,forwards是表示停在最终状态,ease表示运动方式是平滑过渡。

animation: line-1 0.9s forwards ease-in-out; ease-in-out 表示运动方式由慢到快。

animation: jump-1 0.9s reverse ease; reverse表示反方向运行。

transform: translateY(0); translateY(y)定义: 基于原来的位置,沿Y轴平移,长度为y

transform: translateZ(0) rotate(0); translateZ(z)定义:基于原来的位置,沿Z轴平移,长度为zrotate(angle) angle是角度,定义:以图形的几何中心点为旋转中心,顺时针旋转角度为angle

总结

本文介绍了如何用CSS+JS实现Menu Toggle移动菜单切换按钮(打开/关闭),本实例的重点是过渡动画的设计。

您可能对以下文章也感兴趣

  • 漂亮的左侧二级导航菜单(伸缩式)【演示/源码下载】
  • CSS+JS:一款常见的简单大方又实用的移动网页(二级)菜单设计
  • 漂亮的左侧二级导航菜单(伸缩式)【演示/源码下载】
  • 3款有下横线平滑过渡效果的导航栏菜单
  • 非常漂亮的响应式导航栏设计
  • 简单实用的响应式导航菜单设计
  • CSS3实现的可缩进的侧栏导航菜单
  • 漂亮的纯CSS3水平导航菜单(有过渡动画效果)
  • 可以展开和闭合子菜单的CSS3垂直导航菜单
  • 又一个随内容滚动而变化的侧边/左侧目录导航
  • 侧边/左侧目录导航随内容滚动而变化
  • 纯CSS:非常漂亮的左侧导航/内容目录导航
  • 简单却实用的CSS水平和垂直导航栏【演示/源码】
  • CSS3+JQuery实现的三级下拉导航菜单