max-height 可动画而 height: auto 不可,因后者非数值型属性无法插值;max-height 设为略大于内容高度的数值(如240px或600px),配合 overflow: hidden 即可实现平滑展开/收起效果。

max-height 可动画,height: auto 根本没法插值
浏览器的 CSS 动画引擎只对「可计算中间值」的数值型属性生效。height: auto 不是数值,它依赖内容、盒模型、字体加载等运行时计算结果,transition 没法知道“从 0px 到多少 px”,所以写 transition: height 0.3s + height: auto 等于没写——点开瞬间显示,收起直接消失。
max-height 是数值型属性,哪怕设成 max-height: 500px,浏览器也能在 0 → 500 之间做线性插值,配合 overflow: hidden 就自然形成“拉伸/收缩”视觉效果。
height 动画必须精确预知高度,max-height 允许“够用就行”
用 height 做动画,你得在 JS 里先读 scrollHeight,再设目标值,收起时还得手动清回 height: auto,否则后续 JS 计算会出错。而 max-height 只要大于实际内容高度即可,留 20–30px 余量就足够安全。
- 静态内容(如固定段落):估算行高 × 行数 + padding,设
max-height: 240px就很稳 - 动态内容(如 API 渲染列表):仍可先设保守值(如
max-height: 600px),再用 JS 在展开前动态覆盖 - 绝不能设
max-height: 9999px或100vh:前者动画末尾明显拖慢,后者视口缩放时可能突然截断
overflow: hidden 的行为更可控,display 切换完全不可动画
display: none / block 是离散状态切换,transition 对它完全无效;而 max-height 配合 overflow: hidden 是连续控制——只要 overflow: hidden 始终存在(不能只加在 .open 类里),内容就不会撑破容器。
立即学习“前端免费学习笔记(深入)”;
常见翻车点:
- 漏写
overflow: hidden:内容溢出,动画变成“文字往上爬” - 只在
.open里加overflow: hidden:折叠态不生效,初始高度仍占位 - 父级有
transform:可能创建新层叠上下文,导致overflow: hidden失效,需单独验证
移动端和旧浏览器兼容性更稳
max-height + transition 是 CSS2.1 就支持的组合,iOS Safari 10+、Android WebView 4.4+ 全部原生支持;而 @property 控制 height 动画或 clip-path 方案,在 Safari 15.4 之前基本不可用。
真正难的不是让第一版动起来,而是当内容里混入图片、iframe、嵌套 flex 容器时:scrollHeight 可能读早了(图片未加载)、父级 transform 干扰 overflow 截断、字体加载延迟导致行高突变——这些都得靠具体 case 单独处理,没法靠一个通用值兜底。


















