You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CSS实现菜单与关闭图标的切换动画效果?

实现Material Design菜单/关闭图标的平滑切换动画

你的思路方向是对的,但直接替换文本的方式很难实现真正的平滑过渡——毕竟文本切换是瞬间完成的。我们可以通过双图标重叠配合CSS过渡动画的方式,让切换效果更贴合Material Design的流畅感,下面是优化后的完整方案:

方案一:双元素平滑切换(推荐)

这种方式通过两个重叠的图标元素,配合透明度和旋转动画实现自然过渡,是最贴合MD动效风格的做法:

调整HTML结构

把两个图标放在同一个容器内,初始仅显示菜单图标:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div id="icon-container" class="icon-container">
  <span class="material-icons menu-icon">menu</span>
  <span class="material-icons close-icon">close</span>
</div>

优化CSS样式

用绝对定位让图标重叠,通过opacity和transform控制切换动画,搭配MD官方推荐的缓动曲线:

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial;
}

.icon-container {
  position: relative;
  font-size: 60px;
  cursor: pointer;
}

.menu-icon, .close-icon {
  position: absolute;
  top: 0;
  left: 0;
  /* 使用MD官方推荐的缓动曲线,让动画更自然 */
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 初始状态:关闭图标隐藏并旋转 */
.close-icon {
  opacity: 0;
  transform: rotate(90deg) scale(0.8);
}

/* 切换后的激活状态 */
.icon-container.active .menu-icon {
  opacity: 0;
  transform: rotate(-90deg) scale(0.8);
}

.icon-container.active .close-icon {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}

简化JavaScript逻辑

不需要定时器,直接切换容器的类就能触发完整动画:

const iconContainer = document.getElementById("icon-container");
iconContainer.addEventListener("click", function() {
  iconContainer.classList.toggle("active");
});

方案二:单元素文本替换优化(备选)

如果你想保留单图标文本替换的逻辑,可以用transitionend事件替代定时器,精准在动画结束后切换文本,避免时间差导致的生硬感:

调整后的CSS

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  font-family: Arial;
}

#icon {
  font-size: 60px;
  cursor: pointer;
  transition: transform 0.4s ease, opacity 0.3s ease;
}

#icon.animate {
  transform: rotate(180deg) scale(0.8);
  opacity: 0;
}

优化后的JavaScript

let icon = document.getElementById("icon");
icon.addEventListener("click", function() {
  icon.classList.add("animate");
  // 监听过渡结束事件,仅触发一次
  icon.addEventListener("transitionend", function handler() {
    icon.innerText = icon.innerText === "menu" ? "close" : "menu";
    icon.classList.remove("animate");
    icon.removeEventListener("transitionend", handler);
  }, { once: true });
});

内容的提问来源于stack exchange,提问作者VIVEK TAWARE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:37:29