自动轮播跑马灯💡,仅用CSS是否能?
在最近开发✍️的需求中,要求实现类似「跑马灯💡」的效果。所谓「跑马灯💡」,我的理解就是能「自动播放」且「不能滑动」的「轮播图」。
需求
说起「轮播图」,相信大家脑海立马浮现的是「Swiper」。我也一样,很多「轮播图」需求都是用的「Swiper」。
先看效果 ⬇️ :

对于该效果而言,使用「Swiper」有两个缺点:
- 无法实现「无缝滚动」;
- 太「重」;
第一点,可以修改「Swiper」的swiper-wrapper动画的「三次贝塞尔曲线函数」为linear,理论上可以实现「无缝」,但实际上每个swiper-slide切换都会有轻微卡顿,效果不太理想(如果有更好的方法,欢迎👏在评论区留言)。
.swiper-wrapper {
transition-timing-function: linear;
}
第二点,对于不用交互的自动轮播,使用「Swiper」有点臃肿。
所以,能不能仅用「CSS」来实现这个效果呢?
无缝滚动
跑马灯的结构是常见的「html列表」。
<html>
<body>
<div class="scroll">
<ul class="list">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<li class="item">4</li>
<li class="item">5</li>
<li class="item">6</li>
<li class="item">7</li>
</ul>
</div>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
}
.scroll {
width: 400px;
height: 100px;
border: 1px solid red;
}
ul {
display: flex;
}
li {
width: 100px;
height: 100px;
flex-shrink: 0;
box-sizing: border-box;
border: 1px solid green;
}
</style>
</body>
</html>
此时,跑马灯呈现出来的效果 ⬇️ :

接下来,让ul标签动起来,添加animation横向偏移动画:
ul {
display: flex;
animation: scroll 5s linear infinite;
}
@keyframes scroll {
0% {
transform: translate(0px, 0px);
}
100% {
transform: translate(-700px, 0px);
}
}
因为每个li的宽度为100px,所以全部滚动一遍,需要在「X轴」负偏移 100px * 7 = 700px。
跑马灯动态效果如下 ⬇️ :

很明显,还有两个问题:
- 超出部分不应该显示;
- 最后一个
li后面存在空白;
第一个问题很简单,只需要在.scroll中添加overflow: hidden;:
.scroll {
width: 400px;
height: 100px;
overflow: hidden;
border: 1px solid red;
}

解决第二个问题,需要在最后li添加「一屏显示数量」的li。对于上述Demo而言,「一屏数量」为400px / 100px = 4:
<ul class="list">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<li class="item">4</li>
<li class="item">5</li>
<li class="item">6</li>
<li class="item">7</li>
<!-- 额外的li -->
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<li class="item">4</li>
</ul>

这时有小伙伴可能会有疑惑:“我要滚动的数据是从接口拿回来的,数量不固定,要怎么处理?”。
这也很简单,可以使用「css变量」来处理。
<ul class="list" style="--count: 7">
...
</ul>
ul {
display: flex;
animation: scroll calc(var(--count) * 1s) linear infinite;
}
@keyframes scroll {
0% {
transform: translate(0px, 0px);
}
100% {
transform: translate(calc(-100px * var(--count)), 0px);
}
}
配合像「Vue」这种框架,可以很容易把「列表的数量」传给--count,从而适配不同数量的li。
有缝滚动
通过对上述Demo进行改造,也实现类似「Swiper」的自动轮播。
首先,使用css动画的steps()对ul动画进行改写:
ul {
display: flex;
animation: scroll calc(var(--count) * 1s) steps(var(--count)) infinite;
}
区别在于,把「三次贝塞尔曲线函数」替换成steps(),实现逐帧动画。
此时,跑马灯的效果如下 ⬇️ :

初步效果已经有了,接下来为每一个li添加从右到左偏移的动画。
li {
width: 100px;
height: 100px;
flex-shrink: 0;
box-sizing: border-box;
border: 1px solid green;
animation: liScroll 1s infinite;
}
@keyframes liScroll {
0% {
transform: translate(100px, 0px);
}
100% {
transform: translate(0px, 0px);
}
}
最终的效果 ⬇️ :

⚠️:li的animation并没有指定animation-timing-function,默认为ease(开始慢,中间快,结束慢)。如果指定为linear(匀速),则会变成「无缝滚动」。
最后
参考文章:
祝大家生活愉快,工作顺利!
「 --- The end --- 」
转载自:https://juejin.cn/post/7234805296148365372