transition必须写在基础类中,且基础类需显式声明初始值和transition属性,功能类只负责终值;动态插入元素时应先加基础class再appendchild,避免样式未落定导致跳变。

transition 必须写在基础类里,不能只靠切换类触发
浏览器只对「已存在元素的样式变更」做过渡插值。如果 transition 声明只出现在 .active 这类功能类中,而元素刚插入时没这个 class,那它压根没机会参与动画初始化。
常见错误写法:.item.active { opacity: 1; transition: opacity 0.3s; } —— 这会导致第一次加 active 时直接跳变。
- 正确做法:基础类必须同时包含起始值和
transition,例如.item { opacity: 0; transition: opacity 0.3s; } - 功能类只负责终值:
.item.active { opacity: 1; } - 避免用
transition: all 0.3s,Safari 和旧 Edge 会因部分属性不可过渡而整条声明失效
先加 class 再 append,别颠倒顺序
动态创建元素后,如果先 appendChild() 再 classList.add("item"),多数浏览器(尤其是 Firefox)会在单帧内完成布局计算,跳过过渡起点捕捉。
本质是样式还没“落定”,浏览器就完成了渲染流水线。
- 推荐顺序:创建元素 → 立即加基础 class(如
item)→ 再appendChild() - 若必须后加 class,需强制重排:在
add后读取el.offsetHeight或getComputedStyle(el).opacity - 别依赖
setTimeout(, 0),它在 Safari 和低帧率设备上不稳定
Vue scoped 样式会让动态插入的 DOM 匹配失败
<style scoped></style> 会给选择器自动加上 data-v-xxxx 属性,而 JS 直接 appendChild 的节点没有该属性,CSS 规则根本不会生效。
不是 transition 失效,是样式压根没 applied。
- 不要去掉
scoped——这会破坏组件样式隔离 - Vue 2 用
::v-deep(.dynamic-item),Vue 3 用:deep(.dynamic-item)穿透作用域 - 或把过渡相关样式(含基础类和
transition)抽到全局<style></style>块中 - 验证方式:打开 DevTools,检查元素是否有对应 class,且 Computed 面板中
transition不是none
初始值没显式声明,浏览器就“看不见起点”
opacity 默认是 1,transform 默认是 none,但这些“默认”不等于“动画起点”。如果基础类里没写 opacity: 0,浏览器就认为从 1 → 1,变化量为 0,直接跳过。
尤其注意 auto、initial、inherit 这些值,它们无法参与插值计算。
- 所有参与 transition 的属性,必须在基础类中显式写出初始值
- 例如:用
max-height: 0替代height: 0,因为height: auto不可过渡 - 检查 DevTools 的 Computed 面板,确认该属性当前值不是
auto或未定义
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











