用 max-height 替代 height 实现平滑过渡动画,需设合理目标值(如 0→600px)、配合 overflow: hidden 和静态定位,并避免 display: none 或脱离文档流的布局方式。

直接给 max-height 加过渡,但不设固定值,否则动画会卡顿或失效——这是最常被忽略的起点。
为什么 height: auto 不能直接 transition?
CSS 不允许对 height: auto 做过渡动画,浏览器无法计算起始/结束高度差。强行写 transition: height 0.3s 会导致展开瞬间完成、收起时无动画,或完全不生效。
- 常见错误:在 .submenu 上同时写
height: auto和transition: height 0.3s - 正确做法:用
max-height替代height,并配合适当的初始/目标值(如max-height: 0→max-height: 500px) - 关键约束:目标
max-height必须大于子菜单实际内容高度,但不宜过大(比如设成1000px会导致收起时明显延迟) - 配合
overflow: hidden,否则超出部分仍会显示
如何让下方内容真正“被推着动”而不是跳一下?
前提是菜单元素必须参与文档流——任何 position: absolute 或 position: fixed 都会让它脱离布局,下方内容就感知不到高度变化。
- 检查 .submenu 的
position值:必须是static或relative,不能是absolute - 避免父容器设
overflow: hidden:这会裁剪过渡过程中的中间高度,导致动画被截断 - 如果用了 flex 布局,确认父容器没设
flex-shrink: 0或min-height锁死高度 - JS 控制显隐时,别用
display: none切换——它会彻底移除元素,破坏过渡链;改用visibility: hidden+max-height: 0
max-height 过渡怎么设才不僵硬?
数值不是越大越好,也不是越小越快。它得兼顾内容长度变化和动画节奏。
立即学习“前端免费学习笔记(深入)”;
- 推荐用
max-height: 0→max-height: 600px(适用于多数 5–8 项菜单) - 若菜单项数量浮动大,可 JS 动态读取
offsetHeight后设内联max-height,但需注意首次渲染时机 - 收起时,
max-height从当前值过渡到 0,比固定值更顺滑;可用getComputedStyle(el).maxHeight获取当前值 - 过渡时间建议 250–350ms,太短像抽搐,太长让用户等待
真正难的不是写对那几行 CSS,而是确保整个菜单结构没被某个 position: absolute、display: flex 的父容器、或 JS 里一句 el.style.display = 'none' 悄悄破坏掉文档流连贯性。



















