You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重置并重复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&nbsp;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. 帧1在第0-1秒进入,1-8秒显示,8-9秒退出,之后回到初始位置
  2. 帧2在第9-10秒进入,10-17秒显示,17-18秒退出,之后回到初始位置
  3. 文字滚动动画的时序完全对应帧1显示的时间段,在帧1退出后保持结束状态,直到下一轮循环自动重置
  4. 总周期剩余的10秒(18-28秒)是空白等待时间,你可以根据需求调整各部分的时间占比,只要总时长保持25-30秒即可

内容的提问来源于stack exchange,提问作者user2868900

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:36:28