在 CSS 中滑动背景的“技巧”并不新鲜。 事实上,我第一次遇到它可能是几年前的 Valio Con 网站(当前设计不再有它)。 然而,我今天偶然在几个新网站上注意到了它,认为它值得分享。
这就是我们要追求的效果
查看笔 gamYOy by CSS-Tricks (@css-tricks) on CodePen.
请注意,这与 CSS 幻灯片或轮播不同,在 CSS 幻灯片或轮播中,内容被分成可以停止的幻灯片。 这些方面有很好的例子 遍布 CodePen.
此技术获取一个元素的背景,并在 x 轴上无限循环滑动它,从而产生永远循环且始终移动的背景效果。
设置 HTML
这有点像我们的 HTML 需要如何构建的蓝图

有一个元素完全适合视窗的宽度,另一个元素穿过视窗并溢出。 这意味着我们只需要在 HTML 标记中创建两个元素:一个用于背景,另一个用作该背景的容器包装器。
<div class="wrapper">
<div class="sliding-background"></div>
</div>
定位元素
让我们继续添加一些 CSS,这些 CSS 将正确定位我们的两个元素。
.wrapper {
overflow: hidden;
}
.sliding-background {
height: 500px;
width: 5076px;
}
我们的 .wrapper
默认情况下是浏览器宽度的 100%(这就是块级元素的默认行为),并且我们添加了一个 overflow
属性,该属性将隐藏在视觉上包含在它之外的任何内容。 想象一下它就像照片上的裁剪。 包装器之外可能会有额外的东西,但包装器阻止我们看到它。
这就是我们的 .sliding-background
发挥作用的地方。 它被设置为一些荒谬的宽度,这将溢出大多数视窗。 这就是诀窍:它应该是会溢出包装器的宽度。 在这种情况下,我有点武断地选择了 5076px
的宽度。
创建背景图片
如果我们要在屏幕上滚动某些东西,我们需要一张图片,对吧? 这是我们的下一个任务。
还记得我提到我有点武断地选择了 5076px
作为滑动背景的宽度吗? 嗯,它是武断的,但在某种意义上是有意为之的,因为它可以被 3 整除,这适合一分钟循环的计时,我们将在稍后提到。 这意味着我们背景图片的画布是 5076 / 3
或 1692px
。 最终,我们的背景将在无限循环中在一分钟内总共重复三次。 数学大获全胜!
500px
的高度是真正武断的。 您可以根据需要设置它,它将充当背景图片画布的高度。
这是在此示例中使用的 Photoshop 模板,可帮助您入门
保存(并优化!)图片。 这是我们将在 CSS 中用作背景图片的图片
.sliding-background {
background: url("..path/to/image") repeat-x;
height: 500px;
width: 5076px;
}
太棒了! 这就给了我们那张巨大的图片,它溢出包装器,现在可以用来无限地在屏幕上滚动。
滑动效果
好的,让我们让这个坏小子动起来。 我们希望它从左到右循环,一遍又一遍地重复,从而产生一种无缝的效果,让图片看起来永远持续下去。
首先,让我们定义 CSS 动画
@keyframes .slide {
0%{
transform: translate3d(0, 0, 0);
}
100%{
transform: translate3d(-1692px, 0, 0);
}
}
我们使用 transform
属性将左侧图片定位在动画开始时包装器的左侧边缘,如下所示

当动画完成时,它将负向变换位置(从左到右)的量,该量与我们图片的确切宽度相匹配。 而且,由于 .sliding-background
是实际图片宽度的三倍,因此图片在 0% 和 100% 之间重复三次,然后再循环。
注意:我们根本使用额外的 <div>
的原因,而不是在主 <div>
上对 background-position
进行动画处理,是因为我们可以使用动画 transform
来完成移动,这 性能更高。
好的,让我们通过在 .sliding-background
类上调用我们的 slide
动画来完成这些操作
.sliding-background {
background: url("..path/to/image") repeat-x;
height: 560px;
width: 5076px;
animation: slide 60s linear infinite;
}
animation
属性指示 .sliding-background
使用 slide
动画,并以线性、无限循环的方式一次运行一分钟。
将所有内容放在一起
<div class="wrapper">
<div class="sliding-background"></div>
</div>
.wrapper {
overflow: hidden;
}
.sliding-background {
background: url("..path/to/image") repeat-x;
height: 560px;
width: 5076px;
animation: slide 60s linear infinite;
}
@keyframes slide{
0%{
transform: translate3d(0, 0, 0);
}
100%{
transform: translate3d(-1692px, 0, 0);
}
}
这是最终的结果
查看笔 gamYOy by CSS-Tricks (@css-tricks) on CodePen.
不错,我从未想过这一点。
很酷的技巧!
没有 Undertaker 吗?
不酷 :(
对不起! 我也不小心遗漏了所有最好的角色之一,那就是 Junkyard Dog。
很棒的文章……喜欢这些类型的文章……快速易学,技巧很棒,效果也很好……感谢分享……
感谢发布这篇文章! 我正在寻找类似的东西,但我希望它也能以对角线方向滑动并进行缩放。 我想,从大图的概述开始,然后放大到更大图片的特定细节会很不错。
为什么 BG div 是图片宽度的三倍? 两倍(3384px)就足够了,还是我错了?
图片在一分钟内只完全滚动一次,然后才循环。 希望我的意思表达清楚。 英语不是我的母语。 :)
是的,它可以是两倍,当然可以。 我喜欢在更大的显示器情况下使用一个非常大的宽度,但这最终都取决于设计。 :)
使用 translate3d() 相比 background-position 有什么优势吗? 我用后者做过同样的事情,有什么理由我应该使用 translate3d() 而不是它吗?
我认为 transform 是硬件加速的,而 background-position 不是。
translate3d() 是硬件加速的,这意味着在移动设备和平板电脑设备上性能要好得多。
“还记得我提到我有点随意地选择了 5075px 作为滑动背景的宽度吗?嗯,它是随意的,但它是有意为之的,因为它是可以被 3 整除的。”
是吗?
哈哈!也许多一个像素,对吧?我的数学水平真是糟糕,暴露无遗。:)
感谢分享。这让我工作轻松了不少。