用transition配合max-height实现平滑折叠的关键是动态设置max-height:展开前用scrollHeight获取真实高度并内联设置,收起时先移除类名、延迟一帧再设为0;过渡推荐ease-out(展开)和ease-in(收起),时长250–350ms,并确保overflow:hidden及合理处理子元素间距。

用 transition 配合 max-height 实现折叠列表的平滑收起,关键不在“加不加 transition”,而在于 max-height 的取值是否合理——设得太小会提前截断、设得太大又导致动画拖沓或卡顿。
max-height 不能写死固定值(如 500px)
固定值在内容高度变化时会失效:内容少时动画“空跑”半天,内容多时直接被裁切。正确做法是动态匹配真实高度,但 CSS 本身无法读取 JS 计算的高度,所以需配合 JS 获取并内联设置:
- 点击展开前,先用
element.scrollHeight获取容器实际高度 - 将该值设为元素的
style.maxHeight(例如el.style.maxHeight = el.scrollHeight + "px") - 再添加展开类名(触发 transition)
收起时 max-height 要归零,但不能直接设 0
如果收起时直接设 max-height: 0,浏览器可能因渲染优化跳过过渡,导致瞬间消失。稳妥做法是:
- 先移除展开类名,让样式回退到未展开状态
- 用
setTimeout或requestAnimationFrame延迟一帧,再设置maxHeight = "0" - 这样能确保 transition 从当前高度平滑过渡到 0
过渡时间与缓动函数要匹配内容节奏
默认 ease 在开头太快、结尾太慢,容易显得“收不干净”。推荐:
立即学习“前端免费学习笔记(深入)”;
- 展开用
ease-out:起始快,收尾稳,感知更自然 - 收起用
ease-in:缓慢启动,避免突兀消失 - 整体时长建议 250–350ms,太短像抽搐,太长像卡顿
别忘了隐藏溢出和处理子元素 margin/padding
max-height 过渡生效的前提是容器有 overflow: hidden,否则内容会撑开布局;另外子项的上下 margin 和 padding 会影响 scrollHeight 计算,建议:
- 给折叠容器加
overflow: hidden - 子元素垂直间距尽量用
padding-top/bottom替代margin(margin 会塌陷,影响高度测量) - 或统一用
box-sizing: border-box,减少计算误差
基本上就这些。不复杂但容易忽略细节,调通一次,后续复用就很顺了。










