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

如何通过JavaScript实现点击按钮切换方块折叠展开动画(需保留visibility:hidden)

实现带visibility:hidden的方块折叠展开动画

你的代码存在几个关键问题导致动画不生效,以下是问题分析和修正方案:

问题分析

  1. @keyframes语法错误:动画关键帧的百分比后多了冒号(比如0%:),这会导致浏览器无法解析动画规则
  2. 选择器逻辑错误:.expand .retract是后代选择器,只会匹配.expand内部的.retract元素,应该用逗号分隔的并列选择器.expand, .retract来给两个状态类都应用动画
  3. JS初始状态未处理:初始时#box没有expand或retract类,第一次点击按钮时,toggle函数里的两个条件都不满足,不会触发任何类的添加
  4. 高度控制错误:#box设置了固定height:0px,会覆盖max-height的动画效果,应该用max-height来控制折叠展开的高度变化

修正后的完整代码

HTML

<button onclick="toggle()">toggle</button>
<div id="box"></div>

CSS

@keyframes anim {
  0% {
    visibility: hidden;
    max-height: 0px;
  }
  1% {
    visibility: visible;
    max-height: 0px;
  }
  100% {
    visibility: visible;
    max-height: 100px;
  }
}

/* 给两个状态类都应用动画 */
.expand, .retract {
  animation-name: anim;
  animation-duration: 500ms;
  animation-iteration-count: 1;
}

.expand {
  animation-fill-mode: forwards;
}

.retract {
  animation-direction: reverse;
  animation-fill-mode: forwards; /* 改为forwards,确保动画结束后保持最后一帧状态 */
}

#box {
  background-color: red;
  max-height: 0px; /* 用max-height控制初始折叠状态 */
  visibility: hidden;
  width: 50px;
  overflow: hidden; /* 防止内容溢出 */
}

JavaScript

function toggle() {
  let classList = document.getElementById('box').classList;
  
  if (classList.contains('expand')) {
    classList.remove('expand');
    classList.add('retract');
  } else {
    // 处理初始状态(无任何类)和retract状态
    classList.remove('retract');
    classList.add('expand');
  }
}

说明

  • 保留了visibility:hidden的初始状态,动画开始时(1%关键帧)将其设为visible,动画结束后根据状态保持或恢复hidden
  • 用max-height替代固定height来实现平滑的高度过渡,同时添加overflow:hidden避免内容溢出
  • 调整了retract类的animation-fill-mode为forwards,确保收起动画结束后,元素保持visibility:hidden和max-height:0的状态
  • 优化了JS逻辑,处理初始无类的情况,第一次点击即可触发展开动画

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:37:33