如何仅用CSS实现指定加载动画?解决时间同步问题
仅用CSS实现同步加载动画的优化建议
我尝试仅用CSS实现下图的加载动画,但始终无法做好时间同步。目标动画效果如下:
请问有什么实现建议?
现有代码
HTML代码
<div style="display: flex; flex-direction: row; gap: 50px;"> <div style="height:100px;width:100px; background-color: #ccc"> <div class="square"></div> </div> <div style="height:100px;width:100px;border: 1px solid white; position: relative;"> <div id="squareToReveal-1" class="squareToReveal">1</div> <div id="squareToReveal-2" class="squareToReveal">2</div> <div id="squareToReveal-3" class="squareToReveal">3</div> <div id="squareToReveal-4" class="squareToReveal">4</div> </div> </div>
CSS代码
body { background-color: #1E2226; display: flex; justify-content: center; align-items: center; height: 100vh; } .square { width: 50px; height: 50px; background-color: white; position: relative; animation-name: moveSquare; animation-duration: 2s; animation-iteration-count: infinite; } @keyframes moveSquare { 0% {top: 0; left: 0} 25% {top: 0; left: 50%;} 50% {top: 50%; left: 50%;} 75% {top: 50%; left: 0px;} 100% {top: 0px; left: 0px;} } .squareToReveal { width: 50px; height: 50px; background-color: #ccc; opacity: 0; position: absolute; animation-name: revealSquare; animation-duration: 2s; animation-iteration-count: infinite; } #squareToReveal-1 { top: 0; left: 0; animation-delay: 0; } #squareToReveal-2 { top: 0; left: 50%; animation-delay: 0.5s; } #squareToReveal-3 { top: 50%; left: 50%; animation-delay: 1s; } #squareToReveal-4 { top: 50%; left: 0; animation-delay: 1.5s; } @keyframes revealSquare { 0% {opacity: 0;} 25% {opacity: 1;} 75% {opacity: 1;} 100% {opacity: 0;} }
问题分析与优化方案
核心问题
你的代码中,移动方块和显示方块的动画时间节点没有完全对齐:
- 移动动画是平滑过渡(默认
ease函数),但目标动画是步进式切换位置,导致视觉上不同步; - 显示动画的关键帧阶段和移动方块的位置停留阶段不匹配,加上正延迟会让第一次循环出现等待,破坏同步性。
具体优化步骤
- 使用步进动画函数:给两个动画都加上
animation-timing-function: steps(1),让动画瞬间切换状态,完全贴合目标的步进效果; - 对齐关键帧时间线:调整移动动画的关键帧,明确每个位置的停留时间段(比如0%-25%停在左上,25%-50%停在右上);
- 用负延迟实现无缝同步:给显示方块设置负的
animation-delay,让动画直接从对应阶段开始,避免第一次循环的等待,保证循环时的无缝衔接。
修改后的完整代码
HTML代码
<div class="container"> <div class="box" style="background-color: #ccc;"> <div class="square"></div> </div> <div class="box" style="border: 1px solid white;"> <div id="squareToReveal-1" class="squareToReveal">1</div> <div id="squareToReveal-2" class="squareToReveal">2</div> <div id="squareToReveal-3" class="squareToReveal">3</div> <div id="squareToReveal-4" class="squareToReveal">4</div> </div> </div>
CSS代码
body { background-color: #1E2226; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .container { display: flex; gap: 50px; } .box { width: 100px; height: 100px; position: relative; } .square { width: 50px; height: 50px; background-color: white; position: absolute; animation: moveSquare 2s infinite steps(1); } .squareToReveal { width: 50px; height: 50px; background-color: #ccc; position: absolute; opacity: 0; animation: revealSquare 2s infinite steps(1); } #squareToReveal-1 { top: 0; left: 0; } #squareToReveal-2 { top: 0; left: 50%; animation-delay: -0.5s; } #squareToReveal-3 { top: 50%; left: 50%; animation-delay: -1s; } #squareToReveal-4 { top: 50%; left: 0; animation-delay: -1.5s; } @keyframes moveSquare { 0%, 25% { top: 0; left: 0; } 25%, 50% { top: 0; left: 50%; } 50%, 75% { top: 50%; left: 50%; } 75%, 100% { top: 50%; left: 0; } } @keyframes revealSquare { 0%, 25% { opacity: 1; } 25%, 100% { opacity: 0; } }
内容的提问来源于stack exchange,提问作者zeckdude
相关产品推荐
相关产品推荐

