主要思路:先在: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.


一个二次元web开发咸鱼