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

如何实现无间隙无限滚动跑马灯?元素重复滚动问题求助

解决CSS无限滚动跑马灯无间隙问题

要实现无间隙的无限滚动,核心是让滚动元素在移出容器时,有完全相同的元素无缝衔接上。你的现有代码只包含一组元素,动画结束后会跳回起点,导致间隙。以下是修改后的实现方案:

修改后的代码

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>

<div class="marquee">
  <div class="marquee__row">
    <div class="marquee__row__item">
      <i class="fas fa-code"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-html5"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-css3-alt"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-js"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fas fa-microchip"></i> <span> code </span>
    </div>
    <!-- 复制一份元素实现无缝衔接 -->
    <div class="marquee__row__item">
      <i class="fas fa-code"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-html5"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-css3-alt"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-js"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fas fa-microchip"></i> <span> code </span>
    </div>
  </div>
  <div class="marquee__row">
    <div class="marquee__row__item">
      <i class="fab fa-java"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-php"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-sass"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-react"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fas fa-bug"></i> <span> code </span>
    </div>
    <!-- 复制一份元素实现无缝衔接 -->
    <div class="marquee__row__item">
      <i class="fab fa-java"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-php"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-sass"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fab fa-react"></i> <span> code </span>
    </div>
    <div class="marquee__row__item">
      <i class="fas fa-bug"></i> <span> code </span>
    </div>
  </div>
</div>

CSS

.marquee {
  --gap: 1em;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  margin: 0 auto;
  padding: 1em;
  border: 1px solid black;
  background: black;
  overflow: hidden;
  position: relative;
}

.marquee::before,
.marquee::after {
  content: "";
  position: absolute;
  top: 0;
  z-index: 2;
  width: 15%; /* 缩小渐变宽度,避免遮挡过多元素 */
  height: 100%;
  opacity: 1;
  user-select: none;
  pointer-events: none;
}

.marquee::before {
  left: 0;
  background: linear-gradient(to right, black, transparent);
}

.marquee::after {
  right: 0; /* 修正右侧渐变的位置 */
  left: auto;
  background: linear-gradient(to left, black, transparent);
}

.marquee__row {
  display: flex;
  flex-direction: row;
  flex-shrink: 0;
  gap: var(--gap);
  justify-content: flex-start; /* 去掉space-around,让元素紧密排列 */
  animation: marqueeMoveX 10s linear infinite;
}

.marquee__row:hover {
  animation-play-state: paused;
}

.marquee__row:nth-of-type(odd) {
  animation-direction: reverse; /* 使用direction替代play-state:reverse,更稳定 */
}

.marquee__row__item {
  display: flex;
  align-items: center;
  padding: 1em;
  font-size: 1em;
  color: white;
  flex-shrink: 0; /* 防止元素被压缩 */
}

.marquee__row__item i {
  font-size: 5em;
}

@keyframes marqueeMoveX {
  0% {
    transform: translateX(0);
  }
  100% {
    /* 行内有两组元素,移动-50%刚好让第二组接第一组的初始位置 */
    transform: translateX(calc(-50% - var(--gap)/2));
  }
}

关键修改说明

  1. 复制元素组:在每个.marquee__row内复制一份完整的.marquee__row__item列表,当第一组元素移出容器时,第二组完全相同的元素刚好进入视野,视觉上无间隙。
  2. 调整布局属性:
    • 把.marquee__row的justify-content从space-around改为flex-start,让元素紧密排列,避免滚动时出现额外间隙。
    • 给.marquee__row__item添加flex-shrink:0,防止元素在容器空间不足时被压缩变形。
  3. 修正动画位移:行内现在有两组元素,总宽度是原来的2倍,动画终点位移改为calc(-50% - var(--gap)/2),确保动画循环时第二组元素刚好衔接第一组的初始位置。
  4. 修复渐变遮罩位置:把.marquee::after的left:0改为right:0,让右侧渐变遮罩正确显示在容器右端。
  5. 优化反向滚动:用animation-direction: reverse替代animation-play-state: reverse,反向滚动逻辑更稳定,不会出现动画状态异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:17:03