主要思路:先在:root中设置不包括最后一张图的轮播图的个数(最后一张图为第一张图)和每一帧切换的时间,这样做的好处一方面方便css计算属性,一方面可以通过js动态更改图片个数,然后通过ul设置逐帧动画效果使得图片切换,但是这仅是图片的切换效果,图片仍然没有移动,这时就需要再通过li设置补间动画使得li标签中的图片在ul一帧切换的时间内产生平移效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 轮播图</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="carousel">
<ul>
<li>
<img src="../public/images/1.webp" alt="">
</li>
<li>
<img src="../public/images/2.webp" alt="">
</li>
<li>
<img src="../public/images/3.webp" alt="">
</li>
<li>
<img src="../public/images/4.webp" alt="">
</li>
<li>
<img src="../public/images/5.webp" alt="">
</li>
<!-- 补上第一张图片 -->
<li>
<img src="../public/images/1.webp" alt="">
</li>
</ul>
</div>
</body>
</html>
:root{
--speed: 1.5s;
--count: 5;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.carousel{
width: 600px;
height: 400px;
overflow: hidden;
}
.carousel ul{
height: 100%;
display: flex;
flex-wrap: nowrap;
animation: move calc(var(--speed) * var(--count)) steps(var(--count)) infinite;
}
.carousel ul li{
flex-shrink: 0;
width: 100%;
height: 100%;
animation: liMove calc(var(--speed)) infinite;
}
.carousel ul li img{
width: 100%;
height: 100%;
object-fit: cover;
}
@keyframes move {
0%{transform: translateX(0);}
100%{transform: translateX(calc(-1 * var(--count) * 100%));}
}
@keyframes liMove {
0%{transform: translateX(0);}
80%{transform: translateX(0);}
100%{transform: translateX(-100%);}
}
难点:主要是ul设置 display: flex;flex-wrap: nowrap;使得图片全排列在一行之中,但是仅是这样的话图片会平分父元素的宽度,所以li标签还要设置 flex-shrink: 0;使得子元素大小可以随便设置而不被限制
Q.E.D.