animation-iteration-count: infinite 必须显式声明,其默认值为1;简写中infinite须为第5个参数,不可加引号,且易被后续简写覆盖或受dom状态、浏览器策略等影响而中断循环。

animation-iteration-count: infinite 必须显式写,不写就只播一次——这是最常被忽略的硬性前提。
漏写 animation-iteration-count: infinite 就等于没设循环
浏览器对动画的默认行为是播 1 次,animation-iteration-count 的默认值就是 1,不是 infinite。哪怕你写了完整的 @keyframes 和 animation-name,只要没声明这一句,动画播完就停。
- 错误写法:
animation: spin 2s linear;—— 简写里没包含第 5 个参数(iteration-count),自动回退到默认值1 - 正确写法:
animation: spin 2s linear infinite;或单独写animation-iteration-count: infinite; - 引号是致命错误:
animation-iteration-count: "infinite";会失效,infinite是关键字,不能加引号
animation 简写中 infinite 必须是第 5 个参数
animation 是复合属性,完整顺序是:animation: <name><duration><timing-function><delay><iteration-count><direction><fill-mode><play-state></play-state></fill-mode></direction></iteration-count></delay></timing-function></duration></name>。漏掉、错位或覆盖都会让 infinite 失效。
- 如果只写前 4 个值,比如
animation: slide 0.5s ease 0.1s;,那iteration-count就是默认的1 - 想加
alternate又要循环,得写全:animation: slide 0.5s ease 0s infinite alternate;(注意infinite在alternate前) - 后续用简写重置样式时(如 JS 动态设置
element.style.animation = '...'),会把之前单独写的animation-iteration-count覆盖掉
加了 infinite 却“跳帧”或“闪回”,问题不在循环本身
单纯设 infinite 后,每次循环都从 0% 关键帧硬起,如果 0% 和 100% 样式不一致(比如 transform: translateX(0) → translateX(100px)),就会看到瞬间弹回起点。
- 首选方案:让首尾状态自然衔接,例如旋转动画写成
0% { transform: rotate(0deg); }/100% { transform: rotate(360deg); } - 替代方案:加
animation-direction: alternate;,实现正向→反向→正向的往复效果,但要注意100%的值必须能作为下一轮0%的起点,否则仍有跳变 - 慎用
animation-fill-mode: forwards:它只在单次动画结束时生效,和infinite共存时可能掩盖循环起始态,造成“卡住”假象
动画“看似没循环”,大概率是被外部因素中断了
infinite 不代表永不停止,它只表示“只要动画处于激活状态,就重复”。一旦触发暂停条件,循环立刻中止。
-
animation-duration为0s或未声明 → 动画瞬间完成,看起来像没动 - 元素被设为
display: none、visibility: hidden,或移出 DOM → 循环暂停,恢复显示后也不会续播 - 移动端 Safari 在后台标签页会降频甚至暂停动画,这是节电策略,不是 bug
- React/Vue 组件重渲染导致元素重建 → 原动画实例丢失,需用
key或ref手动保活
真正难调的不是怎么写 infinite,而是怎么让动画在各种边界条件下持续跑下去——DOM 存在性、样式优先级、框架生命周期、浏览器后台策略,这些地方比语法更容易出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











