轮播是常见的展示多图和多文字的方式,有很多种类,比如离散周期播放和连续无限播放。
有很多库封装了这一组件,这些库的功能非常强大,可以适应很多场景。但是如果理解了轮播的原理,可以使用 CSS 实现,对于业务中应对多变的需求有很大的帮助。
这篇文章想分享下一个用纯 CSS 实现的无限轮播的方法。
场景
比如,现在有这样一个需求:通过横向移动的文字来展示公告,一条接着一条,第一条接着最后一条,无限循环。
先看效果:
或点击查看网页示例
方法
容器
首先我们创建好容器:
<style>
#wrap {
overflow: hidden;
width: 600px;
white-space: nowrap;
}
</style>
<div id="wrap"></div>
容器为限定宽度,且隐藏溢出内容的 div,设置white-space: norwap
使文本不换行。
文字
加入文字:
<div id="wrap">
<div id="slide">故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 Re So So Si Do Si La So La Si Si Si Si La Si La So </div>
</div>
其中#slide
就是需要移动的文字。
动画
要让文字动起来,设置 animation 属性即可:
<style>
#slide {
animation: slide 10s linear infinite;
}
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
</style>
在文字长度不确定的情况下,我们先假定移动-100%
的距离。
效果如下:
这里有两个问题:
- 移动的距离不是文字的长度
- 文字没有首尾衔接
移动距离
第一个问题出现的原因是transform: translateX
移动的百分不距离是已自身为参照,但是因为#slide
是处于文档流中块级元素,其宽度默认为父元素的宽度。所以文字只会移动 父元素宽度而不是文本本身长度的距离。
要解决这个问题,可以让#slide
脱离文档流,是的文本撑开其宽度即可,我们使用position: absolute
的方法。示例:
<style>
#wrap {
overflow: hidden;
position: relative;
width: 600px;
height: 20px;
white-space: nowrap;
}
#slide {
position: absolute;
animation: slide 10s linear infinite;
}
</style>
效果如下:
首尾相连
我们来看看第二个问题,试想,对于一段文字而言,除非出现虫洞,否则是不可能首尾相连的。那如果有两段一模一样的文本呢?
第一段文本的尾部链接第二段文本的首部,因为两端文本的内容一样,所以在视觉上就好像是一段文本首尾相连了。不过对于第二段文本的末尾又会有首尾不相连的问题,我们总不能 无限制的添加相同的文本来达到效果。
我们知道动画在默认情况下播放完成后是突变的,即播放完成是元素位置突变到初始位置(入上图所示)。文字在移动到最后的部分后,留出一段空白,然后突然又回到开头。我们可 以利用这个突变,想办法让突变前后的视觉效果是一致的。
我们现在有两段相同的文本,试想,我们不需要让两段文本都播放完成。当第一段文本播放完成时,移动了 50%的距离,此时后面衔接了第二段文本的首部。如果此时动画突变到开始 位置,第一段文本的首部代替了此时第二段首部的位置,同时动画又回到了开始的位置。在视觉上,我们感受不到这一位置的突变,因为两段文本是一模一样的。
实现代码如下:
<style>
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
<div id="slide">
<span>故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 Re So So Si Do Si La So La Si Si Si Si La Si La So</span>
<span>故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 Re So So Si Do Si La So La Si Si Si Si La Si La So</span>
</div>
我们把动画的移动距离设置为-50%
,同时安排两段相同的文本。当文本移动两段文本一半的距离(即一段文本的距离)时,动画重新开始,突变到起始位置,在视觉上文本没有移动 ,就有了首尾相连的效果。
延伸一下,对于图片的无限轮播是一样的,在最后一张图片的后面添加一张与第一张图片相同的元素即可。
总结
无限轮播的要点如下:
- 两段相同的文本
- 移动 50% 的距离
Demo 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>无限轮播文字</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#wrap {
overflow: hidden;
position: relative;
width: 600px;
height: 20px;
padding-bottom: 5px;
border-bottom: 1px solid #cccccc;
white-space: nowrap;
}
#slide {
position: absolute;
animation: slide 10s linear infinite;
}
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
</style>
</head>
<body>
<div id="wrap">
<div id="slide">
<span>故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 Re So So Si Do Si La So La Si Si Si Si La Si La So</span>
<span>故事的小黄花 从出生那年就飘着 童年的荡秋千 随记忆一直晃到现在 Re So So Si Do Si La So La Si Si Si Si La Si La So</span>
</div>
</div>
</body>
</html>