display无法过渡,因无中间状态;应改用opacity+visibility协同控制,并通过offsetHeight强制布局触发动画。

display 是离散属性,浏览器根本不计算中间值
你写的 transition: display 0.3s 不是语法错,而是被浏览器静默丢弃——DevTools 的 Computed 面板里压根找不到这条规则。因为 display 只能取 none、block、flex 等枚举值,没有“半显示”这种中间状态,无法插值。一旦设成 display: none,元素立刻从渲染树中移除,连样式计算都停了,其他本可过渡的属性(比如 opacity)也一并失效。
transition: all 0.3s 也不能救 display
很多人以为写 transition: all 0.3s 就能“一劳永逸”,其实只要涉及 display 切换,整条过渡链就断了。浏览器对不可插值属性会直接跳过,不报错、不警告、也不动画。常见误操作包括:
- 在
:hover或临时 class 里声明transition:class 移除后,过渡上下文消失 - JS 中连续执行
el.style.display = 'block'和el.classList.add('fade-in'):浏览器合并渲染,起始帧丢失 - 依赖
height: auto做过渡:auto 不是数值,无法插值,transition: height 0.3s必然失效
用 opacity + visibility 替代时必须显式协同控制
这不是简单替换两个属性,而是分工明确的配合:
-
opacity控制视觉渐变(0 → 1),必须出现在transition列表中 -
visibility控制交互与占位(hidden↔visible),也必须显式声明进transition,否则会瞬切 - 初始态必须同时设
opacity: 0和visibility: hidden;只靠opacity: 0仍挡点击、抢焦点 - 推荐写法:
.el { opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0s 0.25s; },其中visibility 0s 0.25s表示延迟生效,卡在opacity动画结束那一刻
JS 触发时必须打断浏览器的批量渲染
光写对 CSS 不够,JS 操作顺序决定动画是否真正启动:
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
el.style.display = 'block'; el.classList.add('fade-in');→ 合并为一次渲染,无起始帧 - 正确写法:先设
el.style.display = 'block',再读el.offsetHeight(不能用getComputedStyle),最后加 class -
offsetHeight强制触发 layout,让浏览器“看到”元素已就位,才能拿到正确的起始状态 - 高频调用(如滚动中反复显示)慎用该技巧,易引发 layout thrashing 导致卡顿
opacity 动起来,而是判断要不要释放 DOM 占位空间、键盘焦点如何接管、父容器 overflow: hidden 下是否需 JS 补位——这些决策点,往往比 CSS 规则本身更影响最终体验。


















