transition无法直接让元素“不占位”退出,因不支持display/visibility渐变;需先opacity淡出,再JS设display:none或visibility:hidden+pointer-events:none。

transition 无法直接让元素“不占位”退出
transition 本身不支持 display 或 visibility 的渐变,所以你不能写 transition: display 0.3s 或指望 visibility: hidden 淡出——它要么在、要么不在,没有中间帧。想实现“先淡出,再腾出空间”,必须分两步:视觉退出(opacity) + 布局释放(JS 控制 display/visibility)。
正确流程:opacity 过渡完成后才设 display: none
关键不是 CSS 写得多花哨,而是 JS 是否等到了动画真正结束。常见错误是 class 一加,立刻移除 DOM,结果只看到闪一下。
- 基础样式必须包含
transition: opacity 0.3s ease,且初始opacity: 1 - 退出类只改
opacity: 0,**不碰**display或visibility - 监听
transitionend事件,检查event.propertyName === 'opacity',再执行el.style.display = 'none' - 如果需要保留焦点/可访问性,可改用
visibility: hidden+pointer-events: none,而非display: none
为什么不能用 visibility: hidden 配 transition?
visibility 是布尔型属性(visible / hidden),浏览器不对其插值,所以 transition: visibility 0.3s 完全无效。你可能会看到“淡出后突然消失”,那是因为 opacity 到 0 后,visibility: hidden 立即生效,打断了视觉连贯性。更糟的是,如果它和 opacity 同时设在退出类里,浏览器会优先应用 visibility: hidden,直接冻结当前 opacity 值(哪怕还没到 0)。
max-height 替代方案的坑:别用 auto
想做收起动画又不想占位?很多人试 max-height: 0 → max-height: auto,结果没动画。因为 auto 不是数值,浏览器无法计算中间帧。
立即学习“前端免费学习笔记(深入)”;
- 必须用具体像素值,比如
max-height: 0→max-height: 200px - 如果内容高度不确定,得用 JS 先读
el.scrollHeight,再设为max-height - 过渡结束后,仍需 JS 清除
max-height(设回none)并设display: none,否则残留占位
最易被忽略的一点:transition 规则必须写在基础 class 上,而不是只出现在退出类里;否则鼠标移开或状态回退时,浏览器找不到过渡声明,直接硬切。


















