transition必须写在初始css状态中,否则资源加载后直接修改样式无法触发动画;关键是在属性变化前,计算样式中已存在transition声明,可通过el.offsetheight或getcomputedstyle强制重排来确保。

transition 必须写在初始状态,不能等资源加载完再加
直接给元素加 transition 但延迟到 DOMContentLoaded 或图片 load 事件后再触发样式变化,往往没动画——因为浏览器可能已合并重排,跳过过渡。真正生效的前提是:样式变更前,transition 已存在于计算样式中。
-
transition规则必须写在元素的「默认状态」(如.card),不能只写在.card.active或:hover里 - 资源加载完成 ≠ 样式可过渡;关键在于「属性值变化发生时」,该属性是否已被声明为可过渡
- 常见误操作:
img.onload → el.classList.add('loaded'),但.loaded才定义transition,此时变化无过渡
图片/字体加载后触发动画的可靠写法
用 el.offsetHeight 或 getComputedStyle 强制触发重排,让浏览器“看到”初始状态已带 transition,再改样式才有效。
- 先确保 CSS 中已定义好过渡:
.hero-image { opacity: 0; transition: opacity 0.4s ease; } - JS 加载完成后:
img.addEventListener('load', () => { el.style.opacity = '0'; // 确保初始值明确 el.offsetHeight; // 强制重排,锁定当前样式 el.style.opacity = '1'; // 此时才会触发 transition }); - 对字体加载(
fontfaceobserver或@font-face的loading状态),同理:先设visibility: hidden,加载完再设visibility: visible,且transition必须在初始类中
transition 失效的三个典型资源场景
不是所有加载完成都能直接开启动画,这些属性本身就不支持过渡或需额外处理:
-
display: none → block:无效,display不可过渡;改用opacity+visibility或max-height -
height: auto:无法计算中间值,transition 失效;固定高度、或用transform: scaleY()替代 - 背景图
background-image切换:不触发 transition;改用两层元素叠放 +opacity交叉淡入,或用cross-fade()(有限兼容)
更稳妥的加载+动效组合策略
纯 CSS + 少量 JS 协作比硬等资源更可控:
- 给容器加
class="loaded"前,先确保它已有transition声明(哪怕只是opacity 0.1s) - 用
animation处理首次入场(如fade-in),用transition处理后续交互(如 hover 缩放)——避免两者对同一属性冲突 - 关键帧动画结束后,用
animation-fill-mode: forwards固定终态,再启用transition管理后续变化
真正卡住的地方往往不是“怎么加 transition”,而是“什么时候它才算已就绪”。浏览器不会因为你等了图片 load 就自动补上过渡逻辑——你得亲手把它塞进样式链的起点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











