正确做法是将transition声明放在默认样式中,且目标属性需有明确初始值,使用可过渡属性,并确保动态元素完成样式计算后再触发动画。

transition没写在初始状态上
浏览器只在属性值变化时触发过渡,但前提是 transition 声明必须从变化前就存在。如果只写在 :hover、:active 或某个功能类里,那第一次变化就是“突变”——因为过渡上下文根本没建立。
比如:.btn:hover { background-color: #007bff; transition: background-color 0.3s; } 这样写,鼠标移入时背景色瞬间切换,移出时才带动画(而且很可能也不稳定)。
- ✅ 正确做法:把
transition放在默认样式中,例如.btn { transition: background-color 0.3s ease; } - ❌ 错误写法:只在伪类或状态类里声明
transition,哪怕其他属性都对了,动画也大概率不启动 - 验证方式:打开 DevTools → Elements → Computed 面板,搜索
transition-property,确认它在元素“常态”下就存在,而不是只在 hover 后才出现
目标属性没有显式初始值
过渡需要明确的起点和终点才能插值。如果某个属性初始值是 auto、initial 或未声明(比如 left 没设值,默认为 auto),浏览器无法计算中间帧,就会直接跳变。
常见表现:第一次 hover 或 JS 切 class 时“啪”一下到位,第二次才动起来。
- 必须显式写出初始值,例如:
.box { left: 0; width: 100px; opacity: 1; transition: left 0.3s, width 0.3s, opacity 0.3s; } - 特别注意:
width、height、top、left、margin等布局属性极易踩坑;auto和unset都不能作为过渡起点 - 用 Computed 面板确认当前值不是
auto或initial,尤其是从 JS 动态插入的元素,容易漏掉初始样式
改的是不可过渡的 CSS 属性
不是所有属性都能过渡。浏览器只对可计算中间值的属性支持插值,像 display、z-index、position、height(当值为 auto 时)这些,写了 transition 也无效,还不报错。
典型错误:transition: height 0.3s; + height: auto; → 完全不动。
- 可安全过渡的属性包括:
color、background-color、opacity、transform、margin、padding、font-size等 - 替代方案:
height改用max-height(设一个足够大的固定值);display切换改用opacity+transform+overflow: hidden -
background-image默认不可过渡,必须显式声明:transition: background-image 0.5s;
新创建的 DOM 元素没拿到过渡上下文
JS 动态创建元素后立即加 class 触发动画,经常失败。原因不是代码写错了,而是浏览器还没完成样式计算就执行了状态变更——过渡声明和属性变更发生在同一渲染帧,没留下插值空间。
本质是“样式尚未生效,值就变了”,浏览器直接跳过动画。
- 简单解法:强制重排,例如在设置新状态前读一次
offsetHeight:el.offsetHeight; el.classList.add('active'); - 更稳妥做法:用
requestAnimationFrame分帧处理:requestAnimationFrame(() => el.classList.add('active')); - 推荐模式:基础类(含
transition)始终存在,状态类只负责起始/结束值,避免 class 切换导致transition消失
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











