如何重置并重复CSS动画?解决嵌套动画时序错乱问题
解决CSS嵌套动画循环时序错乱问题
核心问题是你当前的动画依赖独立延迟和forwards填充模式,导致循环时元素停留在动画结束状态,无法同步重置。要让每次循环和第一次完全一致,必须把所有动画绑定到同一个总循环周期,用关键帧百分比控制时序,而非独立延迟。
具体修改方案
- 设定总循环时长为28秒(符合25-30秒要求),所有动画统一使用这个时长并开启无限循环
- 移除所有
animation-delay,把原本的延迟转化为对应动画关键帧的起始百分比 - 替换
forwards为both,保证动画结束后能重置回初始状态,为下一轮循环做准备 - 调整帧动画和文字滚动动画的关键帧时间占比,让它们在总周期内同步运行
修改后的完整代码
CSS 部分
* { margin: 0; padding: 0; box-sizing: border-box; } html, body, #banner { width: 320px; height: 320px; border: 1px solid black; position: relative; color: #fff; overflow: hidden; } #banner { background: #000; display: flex; flex-direction: row; } #frame-1, #frame-2 { padding: 30px; font-size: 50px; width: 100%; height: 100%; position: absolute; transform: translateX(150%); /* 总循环时长28秒,无限循环,自动重置状态 */ animation: 28s ease-in infinite both; } #frame-1 { animation-name: frame-1-animation; } #frame-2 { animation-name: frame-2-animation; } .words { font-family: sans-serif; font-size: 20px; line-height: 22px; height: 22px; } .wordlist { position: relative; overflow: hidden; flex-grow: 1; padding-left: 8px; } .word { position: absolute; display: block; transform: translateY(50px); /* 文字动画绑定总循环周期 */ animation: 28s ease-out infinite both; } .word:nth-child(1) { transform: translateY(0px); animation-name: word-first-animation; } .word:nth-child(2) { animation-name: word-second-animation; } .word:nth-child(3) { animation-name: word-third-animation; } .word:nth-child(4) { animation-name: word-fourth-animation; } .subheading__container { display: flex; flex-direction: row; } /* 帧1动画时序:0-3.57%(1秒)进入,3.57%-25%(8秒)显示,25%-28.57%(1秒)退出,后续回到初始位置 */ @keyframes frame-1-animation { 0% { transform: translateX(150%); } 3.57% { transform: translateX(0%); } 25% { transform: translateX(0%); } 28.57% { transform: translateX(-150%); } 100% { transform: translateX(150%); } } /* 帧2动画时序:0-28.57%保持初始位置,28.57%-32.14%(第9秒)进入,32.14%-53.57%(第16秒)显示,53.57%-57.14%(第17秒)退出,后续回到初始位置 */ @keyframes frame-2-animation { 0%, 28.57% { transform: translateX(150%); } 32.14% { transform: translateX(0%); } 53.57% { transform: translateX(0%); } 57.14% { transform: translateX(-150%); } 100% { transform: translateX(150%); } } /* 第一个文字动画:0-2.68%(0.75秒)保持显示,2.68%-10%(2秒)退出 */ @keyframes word-first-animation { 0%, 2.68% { transform: translateY(0); } 10% { transform: translateY(-50px); } 100% { transform: translateY(-50px); } } /* 第二个文字动画:0-5.36%(1.5秒)隐藏,5.36%-14.29%(2.5秒)进入显示,14.29%-21.43%退出 */ @keyframes word-second-animation { 0%, 5.36% { transform: translateY(50px); } 14.29% { transform: translateY(0); } 21.43% { transform: translateY(-50px); } 100% { transform: translateY(-50px); } } /* 第三个文字动画:0-11.25%(3.15秒)隐藏,11.25%-20.18%(2.5秒)进入显示,20.18%-27.32%退出 */ @keyframes word-third-animation { 0%, 11.25% { transform: translateY(50px); } 20.18% { transform: translateY(0); } 27.32% { transform: translateY(-50px); } 100% { transform: translateY(-50px); } } /* 第四个文字动画:0-16.96%(4.75秒)隐藏,16.96%-23.57%(2秒)进入显示,后续保持 */ @keyframes word-fourth-animation { 0%, 16.96% { transform: translateY(50px); } 23.57%, 100% { transform: translateY(0); } }
HTML 部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> /* 上面的CSS代码放在这里 */ </style> </head> <body> <div id="banner"> <div id="frame-1"> <div class="frame-1__container"> <p class="text">This is</p> <p class="text">heading</p> <div class="subheading__container"> <p class="subheading words">This is</p> <p class="words wordlist"> <span class="word">the first word</span> <span class="word">the second word</span> <span class="word">third word</span> <span class="word">fourth word</span> </p> </div> </div> </div> <div id="frame-2"> <div class="frame-2__container"> <p class="text">Lorem</p> <p class="text">Ipsum</p> <p class="text">Dolor</p> </div> </div> </div> </body> </html>
原理说明
所有动画都绑定到28秒的总周期,通过关键帧百分比精准控制每个元素的时序:
- 帧1在第0-1秒进入,1-8秒显示,8-9秒退出,之后回到初始位置
- 帧2在第9-10秒进入,10-17秒显示,17-18秒退出,之后回到初始位置
- 文字滚动动画的时序完全对应帧1显示的时间段,在帧1退出后保持结束状态,直到下一轮循环自动重置
- 总周期剩余的10秒(18-28秒)是空白等待时间,你可以根据需求调整各部分的时间占比,只要总时长保持25-30秒即可
内容的提问来源于stack exchange,提问作者user2868900
相关产品推荐
相关产品推荐

