
本文详解为何 background-size: contain 会破坏 background-repeat: repeat-x 的无缝平铺效果,并提供可直接运行的修复方案,助你轻松实现雾效的无限横向滚动动画。
本文详解为何 `background-size: contain` 会破坏 `background-repeat: repeat-x` 的无缝平铺效果,并提供可直接运行的修复方案,助你轻松实现雾效的无限横向滚动动画。
在实现类似“滚动雾气”的 Marquee 动画时,核心逻辑依赖于背景图的水平重复 + 持续位移。但许多初学者(包括提问者)会意外引入 background-size: contain,这恰恰是导致动画“不循环”或“只滚动一次就消失”的根本原因。
? 问题根源:contain 与 repeat-x 冲突
background-size: contain 的作用是将整张图片完整缩放至容器内可见区域,同时保持宽高比——它强制图片仅渲染一次、居中显示,完全无视 background-repeat: repeat-x 的指令。即使你设置了 repeat-x,浏览器也会优先执行 contain 的约束,结果就是:雾图只出现一次,随后位移后留白,无法形成无缝接续的滚动效果。
✅ 正确做法是:改用 background-size: auto(默认值)或显式指定固定尺寸(如 200vw 100vh),并确保 background-repeat: repeat-x 生效。
✅ 修复后的关键 CSS 片段
.fog-img-first,
.fog-img-second {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: repeat-x; /* 必须保留 */
background-position: top left; /* 避免居中偏移,确保平铺起点一致 */
animation: marquee 60s linear infinite;
}
.fog-img-first {
background-image: url('fog-1.png');
/* 删除 background-size: contain; ✅ */
/* 可选:若需控制单张雾图宽度,用 background-size: 200% 100%; */
}
.fog-img-second {
background-image: url('fog-2.png');
/* 同样删除 contain */
/* 建议添加轻微偏移以增强层次感(见下文) */
}
@keyframes marquee {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-200vw); /* 移动距离 ≥ 图片平铺周期,推荐 200vw 确保无缝 */
}
}
? 进阶优化建议
- 双层错位滚动增强真实感:为 .fog-img-second 添加 animation-delay: -30s,并微调其 background-size(如 180% 100%),使其滚动速度/节奏略异于第一层,营造景深效果。
- 避免布局塌陷:.fog-container 使用 position: absolute 时,请确保父容器(.absolute-bg)有明确高度(如 height: 100vh),否则可能影响渲染。
- 性能提示:使用 translateX() 而非 left,启用 GPU 加速;transform: translate3d(0, 0, 0) 可强制硬件加速(当前代码已包含,很好!)。
⚠️ 注意事项总结
- ❌ 绝对禁止在需要 repeat-x 的元素上使用 background-size: contain 或 cover;
- ✅ background-size: auto 是安全默认值,让图片按原始尺寸平铺;
- ✅ 若需缩放雾图,改用 background-size: [width] [height](如 300px auto),确保宽度可被容器整除以维持无缝;
- ✅ 动画位移终点建议设为 -200vw 或更大,防止因四舍五入导致最后一帧闪白。
修复后,你的雾气将真正实现丝滑、无限、无缝的横向流动效果——无需 JS,纯 CSS 即可胜任。现在,只需删除两行 background-size: contain;,刷新页面,即刻见证流动的朦胧之美。











