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

CSS水平滚动动画:奇偶行反向滚动循环空白问题求助

解决块元素水平无缝循环滚动问题

问题背景

需要实现奇数行从右向左滚动、偶数行从左向右滚动的水平动画,当前已实现基础滚动效果,但元素滚出后会出现空白,无法形成无缝循环。

核心解决思路

要实现无缝循环,关键是让滚动内容在视觉上“首尾相连”。通过复制一份完全相同的滚动内容,让总长度变为原内容的两倍,配合调整动画的滚动距离,当原内容完全滚出容器时,复制的内容刚好衔接上来,视觉上就形成了无限循环的效果。

具体修改步骤

  • 复制滚动内容:给每个.ticker-line添加一份完全相同的.ticker-item列表
  • 调整动画关键帧:
    • 向左滚动动画:滚动距离改为原内容宽度的一半(即总内容的50%),从translateX(0)到translateX(-50%)
    • 向右滚动动画:初始位置设为translateX(-50%),滚动到translateX(0),反向实现无缝衔接
  • 确保内容不换行:给.ticker-line添加flex-wrap: nowrap属性

完整代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        .ticker-container {
            background-color: #333;
            color: #fff;
        }

        .ticker-line-container {
            overflow: hidden;
            margin-bottom: 50px;
        }

        .ticker-line {
            display: flex;
            gap: 50px;
            width: max-content;
            flex-wrap: nowrap; /* 确保内容不换行 */
        }

        .ticker-item {
            width: 300px;
            height: 200px;
            box-sizing: border-box;
        }

        img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        @keyframes ticker-animation-left {
            0% {
                transform: translateX(0);
            }
            100% {
                transform: translateX(-50%); /* 滚动总内容的50%,即原内容的宽度 */
            }
        }

        @keyframes ticker-animation-right {
            0% {
                transform: translateX(-50%); /* 初始位置偏移原内容宽度 */
            }
            100% {
                transform: translateX(0);
            }
        }
    </style>
</head>
<body>

<div class="ticker-container">
    <div class="ticker-line-container">
        <div class="ticker-line" style="animation: ticker-animation-left 15s linear infinite;">
            <!-- 原内容 -->
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=1" alt="Image 1"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=2" alt="Image 2"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=3" alt="Image 3"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=4" alt="Image 4"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=5" alt="Image 5"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=6" alt="Image 6"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=7" alt="Image 7"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=8" alt="Image 8"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=9" alt="Image 9"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=10" alt="Image 10"></div>
            <!-- 复制的内容,实现无缝衔接 -->
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=1" alt="Image 1"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=2" alt="Image 2"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=3" alt="Image 3"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=4" alt="Image 4"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=5" alt="Image 5"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=6" alt="Image 6"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=7" alt="Image 7"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=8" alt="Image 8"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=9" alt="Image 9"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=10" alt="Image 10"></div>
        </div>
    </div>

    <div class="ticker-line-container">
        <div class="ticker-line" style="animation: ticker-animation-right 15s linear infinite;">
            <!-- 原内容 -->
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=11" alt="Image 11"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=12" alt="Image 12"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=13" alt="Image 13"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=14" alt="Image 14"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=15" alt="Image 15"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=16" alt="Image 16"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=17" alt="Image 17"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=18" alt="Image 18"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=19" alt="Image 19"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=20" alt="Image 20"></div>
            <!-- 复制的内容,实现无缝衔接 -->
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=11" alt="Image 11"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=12" alt="Image 12"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=13" alt="Image 13"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=14" alt="Image 14"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=15" alt="Image 15"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=16" alt="Image 16"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=17" alt="Image 17"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=18" alt="Image 18"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=19" alt="Image 19"></div>
            <div class="ticker-item"><img src="https://picsum.photos/300/200?random=20" alt="Image 20"></div>
        </div>
    </div>
</div>

</body>
</html>

说明

  • 复制内容时要保证和原内容完全一致,包括图片链接,这样滚动衔接时才不会出现断层
  • 动画时长保持不变即可,因为滚动距离调整为原内容宽度,速度和原效果一致
  • 若后续需要动态修改内容,需同步更新复制的那份内容,确保两者一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:10:54