animation-direction: alternate 单独无效是因为默认 animation-iteration-count 为 1,必须设为 infinite 或 ≥2 才能往返;且 @keyframes 的 0% 和 100% 帧需样式一致或对称,否则循环掉头时会闪动跳变。

用 animation-direction: alternate 就能实现 CSS 往返动画,但必须搭配 animation-iteration-count: infinite,且 @keyframes 的首尾帧不能突变,否则循环时会跳帧或闪动。
为什么 animation-direction: alternate 单独写没效果?
很多人写了 animation-direction: alternate 却发现动画还是单向跑——因为默认 animation-iteration-count 是 1,只播一次,根本没“往返”的机会。
必须显式声明:
-
animation-iteration-count: infinite(无限循环)或至少 ≥2 -
animation-direction: alternate(或alternate-reverse) - 确保
@keyframes中0%和100%状态兼容(比如都用transform: translateX(),别一个用left一个用transform)
@keyframes 首尾不衔接会导致什么?
往返动画在第 2 次循环开始时,浏览器会从 100% 帧反向走到 0% 帧。如果这两帧的样式不一致(比如 0% 是 opacity: 1,100% 是 opacity: 0.5),就会在“掉头”瞬间出现明显闪烁或位置跳变。
安全做法:
- 让
0%和100%的transform、opacity、color等属性值完全相同(或逻辑对称) - 例如汽车往返:
0%→translateX(0),50%→translateX(500px) rotateY(180deg),100%→translateX(0) - 避免在
0%写margin-left,在100%写transform: translateX()—— 混用布局模型极易断裂
替代方案:不用 alternate,手动写往返关键帧
当逻辑复杂(比如中间要停顿、变速、或首尾状态天然不对称)时,硬凑 alternate 反而难维护。直接把往返过程拆进单次动画里更可控:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
@keyframes shuttle {
0% { transform: translateX(0); }
50% { transform: translateX(300px); }
100% { transform: translateX(0); }
}
.element {
animation: shuttle 4s ease-in-out infinite;
}
这种写法的好处:
- 全程自己定义轨迹,不怕首尾冲突
- 可用
ease-in-out实现自然启停 - 调试时改任意一帧都直观,不用猜
alternate的反向映射
iOS Safari 低版本的渲染坑
iOS 9.3–10.3 对 animation-fill-mode 和 alternate 的组合有 bug:动画最后一帧可能卡住不动,或反向第一帧延迟半拍。不是所有设备都复现,但老 iPad 上很常见。
临时缓解方式:
- 加
animation-fill-mode: forwards(虽不能根治,但减少“回弹前空白”) - 把动画时长设为奇数秒(如
3.7s),避开某些 iOS 渲染管线的帧对齐 bug - 真要兼容到 iOS 9,建议降级用 JS +
requestAnimationFrame手动控制位移,绕过 CSS 动画引擎
真正麻烦的从来不是“怎么写出往返”,而是“怎么让它在各种设备上不抽搐”。首尾帧一致性、iOS 的历史包袱、还有动画被其他样式打断的静默失效——这些细节不验证到真机,上线后就只能靠用户截图来 debug。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










