如何解决网站文本无缝水平滚动动画的停顿问题?
解决无缝水平滚动文本的停顿问题
问题描述
开发即将上线的网站时,需要实现文本以可读速度从右到左无缝水平滚动,但当前效果存在明显停顿。调整关键帧与marquee动画参数后仍未解决,相关代码如下:
原CSS代码
*, *::after, *::before { box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; } body { margin: 0; --color-text: #dedede; --color-bg: #060606; color: var(--color-text); background-color: var(--color-bg); } .hero { -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 10vh 0 25vh; --marquee-width: 100vw; --offset: 20vw; --move-initial: calc(-25% + var(--offset)); --move-final: calc(-50% + var(--offset)); --item-font-size: 8vw; counter-reset: hero; } .marquee { position: absolute; top: 0; left: 0; width: var(--marquee-width); overflow: hidden; pointer-events: none; mix-blend-mode: normal; } .marquee__inner { width: fit-content; display: flex; position: relative; transform: translate3d(var(--move-initial), -0, 0); animation: marquee 5s linear infinite; animation-play-state: paused; opacity: 0; transition: opacity 0.1s; } .marquee .marquee__inner { animation-play-state: running; opacity: 1; transition-duration: 0.4s; } .marquee span { text-align: center; white-space: nowrap; font-size: var(--item-font-size); padding: 0 1vw; font-weight: 900; line-height: 1.15; font-style: regular; color: #FFFB00; } @keyframes marquee { 0% { transform: translate3d(var(--move-initial), 0, 0); } 100% { transform: translate3d(var(--move-final), 0, 0); } }
原HTML代码
<div> <nav class="hero"> <div class="hero__item"> <div class="marquee"> <div class="marquee__inner" style="--tw: 189ch; --ad: 12s;"> <span>Logo Design • Brand Identity • Illustration • Icon Design • UX/UI • Logo Design </span> </div> </div> </div> </nav> </div>
问题根源
- 动画循环衔接断裂:当前动画的起始和结束位置计算未形成无缝循环,动画结束时元素会瞬间跳回起始位置,造成停顿。
- 内容长度不足:单条文本滚动到末尾后,没有衔接的重复内容,导致出现空白间隙。
解决方案
1. 重复文本内容,形成连续流
在marquee__inner中添加多份相同的文本内容,确保滚动时前后内容无缝衔接。
2. 调整动画关键帧参数
修改动画的起始和结束位置,让动画从0滚动到负的单份文本宽度,循环时自然衔接,避免跳变。
3. 优化动画性能
使用translate3d保持GPU加速,确保滚动平滑。
修改后的代码
CSS调整
/* 保留原有基础样式,修改以下部分 */ .marquee__inner { width: fit-content; display: flex; position: relative; /* 移除初始transform,由动画控制 */ animation: marquee var(--ad, 12s) linear infinite; animation-play-state: paused; opacity: 0; transition: opacity 0.4s; } .marquee:hover .marquee__inner { animation-play-state: running; opacity: 1; } @keyframes marquee { 0% { transform: translate3d(0, 0, 0); } 100% { /* 滚动距离为单份文本的负宽度,确保循环衔接 */ transform: translate3d(calc(-100% / 2), 0, 0); } }
HTML调整
<div> <nav class="hero"> <div class="hero__item"> <div class="marquee"> <div class="marquee__inner" style="--ad: 12s;"> <!-- 复制两份相同内容,形成连续滚动 --> <span>Logo Design • Brand Identity • Illustration • Icon Design • UX/UI • </span> <span>Logo Design • Brand Identity • Illustration • Icon Design • UX/UI • </span> </div> </div> </div> </nav> </div>
说明
- 复制两份文本内容后,
marquee__inner的总宽度是单份的2倍,动画滚动到-50%(即单份宽度的负值)时,刚好和起始位置的内容衔接,实现无缝循环。 - 动画时长
--ad可根据需求调整,确保文本滚动速度可读。 - 移除了原有的
--move-initial和--move-final变量,简化逻辑。
内容的提问来源于stack exchange,提问作者onuohaui
相关产品推荐
相关产品推荐

