自动轮播跑马灯💡,仅用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