background-position动画必须用像素或百分比,禁用em/rem;无限滚动需overflow:hidden裁剪、linear缓动、iteration-count:infinite,且background-attachment必须为scroll。

background-position 动画必须用百分比或像素值,不能用 em/rem
用 background-position 做无限滚动背景时,如果写成 background-position: 0 0; → background-position: 100% 100%; 这种过渡,浏览器才能正确插值并形成平滑位移。换成 1em 或 2rem 会导致动画卡顿甚至直接不触发——因为单位不一致时,CSS 动画引擎无法线性计算中间帧。
常见错误现象:background-position: 0 0; → background-position: 100vw 100vh; 看起来“动了”,但实际是整张图被拉伸重绘,不是滚动效果。
- 推荐写法:起始
0% { background-position: 0 0; },结束100% { background-position: -200px -200px; }(像素)或100% { background-position: 100% 100%; }(百分比) - 如果贴图宽高是 200px × 200px,要无缝循环,位移终点建议设为
-200px -200px,而不是200px 200px,否则方向反了 - 百分比方案更适合响应式背景,但需确保容器尺寸固定或使用
background-size: cover;配合,否则百分比基准会漂移
relative 容器不是必须的,但 overflow: hidden 是关键
很多人以为必须套一层 position: relative; 才能做背景滚动,其实不是。真正起作用的是容器的 overflow: hidden; ——它把超出区域的背景切掉,让“滚动”看起来是局部发生的。没有它,你会看到背景一路往右下跑出屏幕,根本不是“无限滚动”效果。
使用场景:全屏 banner、卡片 hover 背景微动、loading 动效。
立即学习“前端免费学习笔记(深入)”;
-
position: relative;只在你需要绝对定位子元素(比如叠加文字层)时才需要,和背景动画本身无关 - 容器高度必须明确(如
height: 400px;或aspect-ratio: 16/9;),否则background-position百分比计算无锚点 - 如果父容器是 flex/grid 项,记得检查是否被
align-items: stretch;拉高导致意外留白
@keyframes 动画时间与 iteration-count 要匹配贴图尺寸
动画太快,滚动感像闪屏;太慢,用户等不到循环就划走了。核心判断依据是贴图自身尺寸和期望滚动速度。
假设你用一张 400px 宽的横向条纹图,想模拟匀速向左滚动,那么:
- 动画周期设为
4s,位移写background-position: -400px 0;→ 平均速度就是 100px/s - 必须加
animation-iteration-count: infinite;,否则只播一次就停住 - 别用
ease缓动函数——它会让开头结尾变慢,破坏“匀速滚动”的错觉;linear是唯一合理选择 - 如果贴图是重复平铺(
background-repeat: repeat;),位移量必须是贴图宽高的整数倍,否则接缝处会跳变
移动端 Safari 对 background-attachment: fixed 的兼容性会破坏滚动效果
如果你在实现“视差滚动背景”时误用了 background-attachment: fixed;,在 iOS Safari 上大概率失效——它会退化成 scroll,导致动画完全不动或抖动。无限滚动背景必须全程用 background-attachment: scroll;(这也是默认值)。
容易踩的坑:
- 某些 CSS 重置库(如 modern-normalize)会全局设置
background-attachment: unset;,导致动画失灵,得显式覆盖回scroll - 不要在动画中动态改
background-size,Safari 15–16 对它的动画支持极差,会卡顿或跳帧 - 真机调试时,开启
transform: translateZ(0);可能提升渲染帧率,但仅限于有性能瓶颈时加,不是必需
最稳的组合:固定尺寸容器 + overflow: hidden; + linear 动画 + 像素/百分比位移 + 显式声明 background-attachment: scroll;。其他都是干扰项。










