用max-height配合transition实现收缩动画需设具体数值(如100px)和overflow:hidden,初始状态与动画状态均需定义;删除时须先加类触发动画,监听transitionend且校验propertyname为max-height后再移除元素。

用 transition 配合 max-height 实现收缩动画
直接改 height: 0 不会动,因为高度从具体值(如 24px)跳到 0 时,浏览器无法插值;max-height 是更稳妥的选择——只要设一个略大于实际内容的固定上限(比如 100px),浏览器就能平滑过渡。
常见错误是把 transition 写在 :hover 或点击后的类上,却忘了初始状态也要有 max-height 和 overflow: hidden,否则动画不触发。
-
max-height值必须是具体数字(px、em),不能用fit-content或auto - 初始状态要设
overflow: hidden,否则内容会撑开容器、动画失效 - 删除时建议用
transform: scaleY(0)+opacity: 0配合max-height,视觉更自然
li {
max-height: 100px;
overflow: hidden;
transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
}
li.removing {
max-height: 0;
opacity: 0;
}
JavaScript 删除元素前必须先加 class 触发动画
DOM 直接 remove() 或 innerHTML = '' 会跳过动画——浏览器没机会渲染中间帧。必须分两步:先加一个标记类(比如 removing),等动画结束再真删。
容易踩的坑是监听 transitionend 但没过滤属性名,导致 opacity 和 max-height 各触发一次,删早了。
立即学习“前端免费学习笔记(深入)”;
- 用
el.addEventListener('transitionend', handler, { once: true })避免重复绑定 - 在
handler里检查e.propertyName === 'max-height',只在这时执行el.remove() - 如果列表项高度差异大,
max-height统一设成最大可能值(比如200px),避免短项动画过慢
用 will-change 提升动画性能(但别滥用)
列表项多或滚动区域复杂时,max-height 动画可能掉帧。加 will-change: max-height 能让浏览器提前准备合成层,但只应在动画开始前一刻加,结束后立刻移除。
误用 will-change 的典型表现是页面滚动卡顿、内存占用飙升——它不是开关,而是提示“接下来我要动这个属性”,长期挂着等于持续开销。
- 在 JS 加
removing类的同时,用el.style.willChange = 'max-height' - 在
transitionend回调里,删完元素后立即写el.style.willChange = 'auto' - 不要在 CSS 里全局写
will-change: max-height,毫无意义且有害
Flex/Grid 布局下 max-height 动画可能失效
如果列表项父容器用了 display: flex 或 grid,子项设 max-height 有时完全不动——flex item 默认不响应 max-height,它优先按内容撑开。
解决办法不是硬套 align-self: flex-start,而是换思路:用 transform: scaleY() 主导动画,max-height 只作兜底。
- 给列表项加
align-self: flex-start+margin-bottom: 0,确保它不被 flex 拉伸 - 更可靠的做法是放弃
max-height,纯用transform: scaleY(0)+opacity: 0,并配transform-origin: top - 注意:
transform动画不会触发重排,但scaleY(0)后仍占文档流空间,需额外设position: absolute或用visibility: hidden收尾










