必须同时定义@keyframes、animation-duration和transform-origin,且首尾状态单位统一(如0deg→360deg)、动画名严格匹配、transform-origin设为center、timing-function用linear,简写animation时按正确顺序一次性写全。

直接写 animation-iteration-count: infinite 不会自动转起来——漏掉 @keyframes 定义、animation-duration 或 transform-origin,旋转要么不动、要么绕左上角乱甩、要么播完一圈就卡住。
必须显式定义 @keyframes 且首尾状态一致
浏览器靠首帧和末帧的差值做插值;如果只写 to { transform: rotate(360deg); },部分 Safari 会无法推导起始态,导致第一圈不触发。更糟的是,若末帧是 rotate(360deg) 而首帧是 rotate(0),但单位混用(比如一个写 0,一个写 360deg),旧版 Safari 可能解析失败。
- 最简可靠写法:
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } - 避免用
0%/100%混合单位,统一用deg - 别把动画名写成
spin(带空格)或大小写不匹配,animation-name: Spin和@keyframes spin不生效
transform-origin 不设就是绕左上角转
默认 transform-origin: 0 0,对宽高不固定或有 padding 的容器,旋转中心会偏移,看起来像“甩出去”。尤其当元素是 inline 元素(如 <span>),不加 display: inline-block 就设 transform-origin,样式会被忽略。
- 绝大多数场景应显式写:
transform-origin: center(IE9+ 支持,比50% 50%更稳) - 避免用
top left这类关键词组合,不同浏览器解析有差异 - 如果父容器是 flex/grid 且设了
align-items: center,某些 Chrome 版本下旋转可能卡在第一帧——临时解法是加transform: translateZ(0)强制 GPU 层
animation-timing-function 默认 ease 会造成顿挫感
ease 是先慢→快→慢,一圈结束瞬间有明显停顿,连续播放时像“卡了一下”。这不是循环失效,而是节奏问题。
立即学习“前端免费学习笔记(深入)”;
- 真要匀速转,必须写:
animation-timing-function: linear - 想模拟机械齿轮感,可用:
cubic-bezier(0.3, 0.7, 0.7, 0.3) - 别把
animation-play-state: paused遗留在样式里,调试完不删,动画永远不启动 - 简写中漏掉
linear,浏览器按默认ease处理,容易误判为“转得不顺”
用 animation 简写时顺序和覆盖逻辑很关键
单独写 animation-iteration-count: infinite 很危险——后面只要出现一行 animation: spin 1.5s 这样的简写,整个动画配置就被重置,iteration-count 回退到默认值 1。
- 推荐一次性写全:
animation: spin 1.5s linear infinite; - 顺序不能错:时长 → timing-function → 延迟 → iteration-count → direction → fill-mode
- 如果要用
animation-fill-mode: forwards,必须放在infinite后面,例如:animation: spin 1.5s linear infinite forwards; -
animation-delay只影响第一次播放前,不会在每次循环前重复延迟
真正难调的不是“怎么让它转”,而是“为什么转得不像绕中心匀速转”——问题往往出在 transform-origin 隐式继承、@keyframes 单位不统一、或父容器 layout 触发的重绘冲突上。这些细节不报错,但让动画看起来“不对劲”。


















