display: none 无法触发 transition,应改用 opacity+visibility 实现淡入淡出,或 max-height+overflow 实现展开收起;transform 单独使用存在缩放中心和定位偏差问题。

transition 不能直接作用于 display: none
很多初学者会写 display: none + transition: all 0.3s,发现完全没动画——因为 display 是离散属性,浏览器不支持过渡。必须改用可过渡的属性,比如 opacity、height、transform 或 visibility 配合其他属性。
用 opacity + visibility 实现最简平滑淡入淡出
这是兼容性最好、代码最少的方案,适合大多数弹窗(如提示框、确认框),不需要高度变化。
-
visibility: hidden让元素不可见且不占布局空间,但能触发过渡 -
opacity: 0控制透明度,配合transition实现淡入淡出 - 必须同时控制
visibility和opacity,否则隐藏时仍可能被聚焦或影响 tab 键顺序
.modal {
opacity: 0;
visibility: hidden;
transition: opacity 0.25s ease, visibility 0.25s;
}
.modal.show {
opacity: 1;
visibility: visible;
}
用 height + overflow 实现“展开/收起”式过渡
适用于内容高度固定或可预估的弹窗(如抽屉菜单、折叠面板),需要动态控制高度。
- 不能直接对
height: auto做过渡——浏览器无法计算中间值 - 常见解法:用
max-height替代height,设一个足够大的安全值(如max-height: 500px) - 配合
overflow: hidden防止内容溢出 - 注意:如果真实高度超过
max-height,动画会卡在截断处
.modal-collapse {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease, opacity 0.3s ease;
opacity: 0;
}
.modal-collapse.open {
max-height: 500px;
opacity: 1;
}
为什么不用 transform: scale() 单独做?
transform 性能好,但单独用 scale(0) → scale(1) 有明显缺陷:
立即学习“前端免费学习笔记(深入)”;
- 缩放中心默认是左上角,视觉上像从角落“炸开”,不符合多数弹窗居中浮现预期
- 必须手动加
transform-origin: center才能居中缩放 - 若弹窗含绝对定位子元素(如关闭按钮),缩放会影响其定位基准,容易错位
- 不如
opacity + visibility组合稳定,尤其在旧版 Safari 中transform过渡偶发跳帧
真正要兼顾性能和体验,推荐组合: opacity + transform: translateY() + visibility,避免重排,也规避了 height 的估算风险。










