
本文详解通过统一父容器动画替代子元素独立动画,配合 flex 布局与精确尺寸控制,彻底解决多图水平无缝滚动时出现的细小白色缝隙(stuttering white line)问题。
本文详解通过统一父容器动画替代子元素独立动画,配合 flex 布局与精确尺寸控制,彻底解决多图水平无缝滚动时出现的细小白色缝隙(stuttering white line)问题。
在实现无限横向滚动波浪式头部动画时,一个常见却极易被忽视的问题是:当两个相同图片并排、各自独立执行 translateX(-100%) 动画时,浏览器渲染引擎可能因子元素动画时间微差、像素对齐误差或 sub-pixel 渲染抖动,在拼接处产生一条细小的白色间隙——尤其在高 DPI 屏幕或 Gatsby 等现代构建工具中更为明显。这不是 margin 或 padding 导致的空白,而是动画同步失准 + 布局碎片化引发的视觉断层。
根本解法是放弃“每个 .imWrapper 单独动画”的思路,转而将动画逻辑上收至父容器统一驱动,让所有子图作为静态、连续的整体参与位移。以下是推荐的健壮实现:
/* 全局防溢出,避免滚动条干扰 */
html, body {
margin: 0;
padding: 0;
overflow-x: hidden; /* 关键:禁用横向滚动,防止动画触发重排抖动 */
}
.img-container {
display: flex;
width: 200%; /* 两图总宽,确保无缝衔接 */
animation: slide 10s linear infinite;
/* 防止图片默认 inline 行内基线对齐产生的底部空隙 */
font-size: 0;
line-height: 0;
}
.img-container img {
flex: 0 0 50%; /* 每张图严格占 50% 容器宽度 */
height: auto;
display: block; /* 消除 inline 元素默认间距 */
}
@keyframes slide {
from {
transform: translateX(0);
}
to {
transform: translateX(-50%); /* 注意:此处为 -50%,非 -100%!因为容器总宽是 200% */
}
}<div class="img-container"> <img src="https://i.imgur.com/gvpbX3j.png" alt="wave background"> <img src="https://i.imgur.com/gvpbX3j.png" alt="wave background"> </div>
✅ 关键要点说明:
- 动画位移量必须匹配布局比例:容器设为 width: 200%,两张图各占 50%,因此动画终点应为 translateX(-50%),才能让第二张图完全滑至视口左端,第一张图恰好补全右侧——形成数学级无缝循环。
- display: flex + flex: 0 0 50% 确保图片无间隙排列,规避 inline-block 的幽灵空白(ghost whitespace)问题。
- font-size: 0 和 display: block 双重保障,彻底消除行内元素固有基线间隙。
- 若使用 Gatsby 的 <StaticImage />,请将其包裹在 <div style={{ display: 'block' }}> 中,并确保其父 img 标签样式继承一致;也可直接对 StaticImage 组件设置 layout="constrained" 并指定 width/height 以保证渲染稳定性。
⚠️ 避坑提醒:
不要尝试用 margin-left: -1px 或 backface-visibility: hidden 等 hack 方式掩盖缝隙——这无法根治渲染不同步问题,且在缩放或不同设备下易失效。真正的无缝,源于结构设计的严谨性与动画作用域的合理性。
通过此方案,你将获得真正平滑、无闪烁、跨浏览器一致的无限滚动效果,为 Wave Header 打下坚实的视觉基础。

















