无限横向滚动动画闪烁与空白问题解决咨询
解决无限滚动动画的闪烁与首尾空白问题
问题根源
当前实现仅复制了一次内容,当原内容总宽度小于容器max-width(1300px)时,复制后的内容依然无法填满容器的两倍宽度,导致动画滚动到终点时首尾元素间出现大量空白;同时固定的动画偏移值calc(-50% - 0.5rem)无法适配内容宽度不足的场景,造成循环衔接时的闪烁。
修复方案
通过动态计算内容复制次数、调整动画偏移逻辑,确保内容总宽度覆盖容器两倍宽度,实现无缝循环。
修改后的JavaScript代码
const scrollers = document.querySelectorAll(".scroller"); if (!window.matchMedia("(prefers-reduced-motion: reduce)").matches) { addAnimation(); } function addAnimation() { scrollers.forEach((scroller) => { scroller.setAttribute("data-animated", true); const scrollerInner = scroller.querySelector(".scroller__inner"); const scrollerContent = Array.from(scrollerInner.children); const containerWidth = scroller.offsetWidth; let totalContentWidth = scrollerInner.scrollWidth; // 循环复制内容,直到总宽度至少为容器的2倍 while (totalContentWidth < containerWidth * 2) { scrollerContent.forEach((item) => { const duplicatedItem = item.cloneNode(true); duplicatedItem.setAttribute("aria-hidden", true); scrollerInner.appendChild(duplicatedItem); }); totalContentWidth = scrollerInner.scrollWidth; } // 记录内容重复次数,用于动画偏移计算 const contentCount = scrollerInner.children.length / scrollerContent.length; scrollerInner.style.setProperty("--_content-count", contentCount); }); }
修改后的CSS动画部分
.scroller[data-animated="true"] .scroller__inner { width: max-content; flex-wrap: nowrap; --_content-count: 2; /* 默认值,JS会动态覆盖 */ animation: scroll var(--_animation-duration, 40s) var(--_animation-direction, forwards) linear infinite; } @keyframes scroll { to { /* 根据内容重复次数计算偏移量,确保无缝衔接 */ transform: translate(calc(-100% / var(--_content-count))); } }
关键调整说明
- 动态复制内容:通过循环复制原内容,直到总宽度达到容器的2倍,保证滚动过程中容器始终被内容填充,消除首尾空白。
- 自适应动画偏移:用CSS变量记录内容重复次数,动画终点偏移量改为
calc(-100% / var(--_content-count)),确保滚动到终点时刚好衔接开头,彻底解决闪烁。 - 兼容原有特性:原有的方向(
data-direction)、速度(data-speed)控制逻辑完全保留,不影响原有功能。
内容的提问来源于stack exchange,提问作者tech27
相关产品推荐
相关产品推荐

