
通过结合 `classlist.toggle()` 与 css `transition`(而非 `animation`),可高效实现元素高度的平滑展开与收起,同时避免 `visibility` 导致的动画失效问题。
要实现一个类似“折叠面板”的点击展开/收起效果(如红色方块从隐藏状态平滑展开为 100px 高),关键在于用 height + overflow: hidden + transition 替代 visibility + animation。因为 visibility 是离散属性(visible/hidden),无法参与 css 过渡或关键帧动画;而 height 是可过渡的连续属性,配合 overflow: hidden 可自然实现“伸缩”视觉效果。
以下是完整、简洁且可靠的实现方案:
✅ html 结构(保持简洁):
✅ CSS 样式(核心:仅需一个 .expand 类 + 过渡):
立即学习“Java免费学习笔记(深入)”;
#box { width: 50px; height: 0; overflow: hidden; /* 关键:隐藏超出部分,使 height=0 时完全不可见 */ background-color: red; transition: height 0.5s ease-in-out; /* 平滑过渡,时长可调 */ } #box.expand { height: 100px; /* 展开后的目标高度 */ }
✅ javaScript 逻辑(极简健壮):
function toggle() { const box = document.getElementById('box'); if (box) box.classlist.toggle('expand'); }
✅ 推荐写法(ES6 箭头函数 + 可选链):const toggle = () => document.getElementById(‘box’)?.classList.toggle(‘expand’);
? 为什么原方案失败?
- visibility 不支持过渡/动画(浏览器会跳变);
- .expand .retract 是后代选择器,语义错误(一个元素不可能同时是自己后代);
- max-height 虽可过渡,但需预设足够大的值,精度差且易出布局抖动;而 height 直接控制,更精准可控。
? 进阶提示:
- 若需支持内容高度自适应(非固定 100px),可用 max-height + transition,并设置足够大的 max-height: 500px(需确保大于实际内容);
- 添加 will-change: height 可提升动画性能(尤其在复杂页面中);
- 为无障碍考虑,建议同步切换 aria-expanded 属性与 tabindex。
该方案轻量、语义清晰、兼容性好(支持所有现代浏览器及 IE10+),是折叠动画的最佳实践之一。