CSS Animation左右方向动画速度不一致问题修复求助
解决CSS方块动画正反向节奏不一致的问题
我是CSS Animation新手,已实现如下方块移动动画:
body { display: flex; justify-content: center; align-items: center; height: 100vh; /*background-color: #333;*/ margin: 0; } .loader { position: relative; width: 14vh; height: 8vh; } .square { width: 2vh; height: 2vh; border-radius: 0.4vh; position: absolute; margin: 1vh; } .square.A { left: 0; top: 4vh; background-color: #31473A; -webkit-animation: moveA 6s infinite 0.25s alternate; animation: moveA 6s linear infinite 0.25s alternate; } .square.B { left: 3vh; top: 4vh; background-color: #26382E; -webkit-animation: moveB 6s infinite 0.5s alternate; animation: moveB 6s linear infinite 0.5s alternate; } .square.C { left: 6vh; top: 4vh; background-color: #1c2921; -webkit-animation: moveC 6s infinite 0.6s alternate; animation: moveC 6s linear infinite 0.6s alternate; } .square.E { left: 0; top: 0; background-color: #3B5144; -webkit-animation: moveE 6s infinite alternate; animation: moveE 6s linear infinite alternate; } @keyframes moveA { 0% { top: 4vh; } 5% { top: 6.5vh; left: 0; } 10% { top: 6.5vh; left: 3vh; } 15% { top: 4vh; left: 3vh; } 100% { top: 4vh; left: 3vh; } } @keyframes moveB { 0%, 5% { top: 4vh; left: 3vh; } 12% { top: 1.5vh; left: 3vh; } 20% { top: 1.5vh; left: 6vh; } 25% { top: 4vh; left: 6vh; } 100% { top: 4vh; left: 6vh; } } @keyframes moveC { 0%, 15% { top: 4vh; left: 6vh; } 25% { top: 6.5vh; left: 6vh; } 35% { top: 6.5vh; left: 9vh; } 40% { top: 4vh; left: 9vh; } 100% { top: 4vh; left: 9vh; } } @keyframes moveE { 0% { top: 0; left: 0; } 10% { top: 4vh; left: 0; } 100% { top: 4vh; left: 0; } }
<div class="loader"> <div class="square A"></div> <div class="square B"></div> <div class="square C"></div> <div class="square E"></div> </div>
该动画从左到右时符合预期(同一时间仅一个方块移动),但因使用alternate属性,从右到左时方块移动速度过快。尝试过更换animation-timing-function(如linear、ease-in-out)及调整关键帧百分比,但要么无效,要么破坏左到右的动画效果。求最优解决方法,使左右方向均能保持同一时间仅一个方块移动的预期效果。
问题原因
alternate属性会让动画在偶数次迭代时反向播放,但你的关键帧是仅为正向流程设计的:正向时每个方块只在特定时间段移动,其余时间静止;反向播放时,动画会倒序执行关键帧,原来的长静止段(比如15%-100%)会被压缩成反向移动的过渡段,导致移动速度陡增。同时,alternate不会反转动画延迟的顺序,进一步打乱了反向时的移动节奏。
最优解决方案
放弃alternate,手动编写包含正向移动→静止→反向移动→静止的完整循环关键帧,让动画周期覆盖正反向全流程,完全控制每个阶段的时间占比,确保正反向节奏一致。
修改后的代码
body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .loader { position: relative; width: 14vh; height: 8vh; } .square { width: 2vh; height: 2vh; border-radius: 0.4vh; position: absolute; margin: 1vh; } .square.A { left: 0; top: 4vh; background-color: #31473A; animation: moveA 12s linear infinite 0.25s; } .square.B { left: 3vh; top: 4vh; background-color: #26382E; animation: moveB 12s linear infinite 0.5s; } .square.C { left: 6vh; top: 4vh; background-color: #1c2921; animation: moveC 12s linear infinite 0.6s; } .square.E { left: 0; top: 0; background-color: #3B5144; animation: moveE 12s linear infinite; } /* 方块A的完整循环:正向移动→静止→反向移动→静止 */ @keyframes moveA { /* 正向阶段(0%-50%) */ 0% { top: 4vh; left: 0; } 4.17% { top: 6.5vh; left: 0; } 8.33% { top: 6.5vh; left: 3vh; } 12.5% { top: 4vh; left: 3vh; } 50% { top: 4vh; left: 3vh; } /* 反向阶段(50%-100%) */ 54.17% { top: 4vh; left: 3vh; } 58.33% { top: 6.5vh; left: 3vh; } 62.5% { top: 6.5vh; left: 0; } 66.67% { top: 4vh; left: 0; } 100% { top: 4vh; left: 0; } } /* 方块B的完整循环 */ @keyframes moveB { /* 正向阶段 */ 0%, 4.17% { top: 4vh; left: 3vh; } 10% { top: 1.5vh; left: 3vh; } 16.67% { top: 1.5vh; left: 6vh; } 20.83% { top: 4vh; left: 6vh; } 50% { top: 4vh; left: 6vh; } /* 反向阶段 */ 54.17%, 58.33% { top: 4vh; left: 6vh; } 65% { top: 1.5vh; left: 6vh; } 71.67% { top: 1.5vh; left: 3vh; } 75.83% { top: 4vh; left: 3vh; } 100% { top: 4vh; left: 3vh; } } /* 方块C的完整循环 */ @keyframes moveC { /* 正向阶段 */ 0%, 12.5% { top: 4vh; left: 6vh; } 20.83% { top: 6.5vh; left: 6vh; } 29.17% { top: 6.5vh; left: 9vh; } 33.33% { top: 4vh; left: 9vh; } 50% { top: 4vh; left: 9vh; } /* 反向阶段 */ 54.17%, 62.5% { top: 4vh; left: 9vh; } 70.83% { top: 6.5vh; left: 9vh; } 79.17% { top: 6.5vh; left: 6vh; } 83.33% { top: 4vh; left: 6vh; } 100% { top: 4vh; left: 6vh; } } /* 方块E的完整循环 */ @keyframes moveE { /* 正向阶段 */ 0% { top: 0; left: 0; } 8.33% { top: 4vh; left: 0; } 50% { top: 4vh; left: 0; } /* 反向阶段 */ 58.33% { top: 4vh; left: 0; } 66.67% { top: 0; left: 0; } 100% { top: 0; left: 0; } }
<div class="loader"> <div class="square A"></div> <div class="square B"></div> <div class="square C"></div> <div class="square E"></div> </div>
关键调整说明
- 动画时长翻倍:从6秒改为12秒,包含6秒正向流程+6秒反向流程,确保正反向时间占比一致。
- 移除
alternate属性:通过关键帧手动定义反向移动逻辑,避免自动反向带来的节奏混乱。 - 对称关键帧:每个方块的反向移动阶段(50%-100%)是正向阶段(0%-50%)的镜像,移动时间占比完全相同,保证正反向移动速度一致。
- 保持延迟逻辑:保留原有的动画延迟,确保正向时的移动顺序(E→A→B→C)和反向时的顺序(C→B→A→E)衔接自然,同一时间始终只有一个方块在移动。
内容的提问来源于stack exchange,提问作者Payas Hasteer
相关产品推荐
相关产品推荐

