制作无限 CSS 轮播

2025-06-07

制作无限 CSS 轮播

经过数小时的搜索和摸索,我依然没能找到一个关于如何制作无限 CSS 轮播的好指南。这完全可以用 HTML 和 CSS 来实现,然而几乎每个指南都用 JavaScript 或 CSS,而且尝试一下根本就行不通。

它非常简单,但却没有可用的工作示例,因此我将在 Authress公司网站上分享我们为制作品牌轮播所做的事情。

当然,您首先想看看成品:
rhosys 品牌轮播

深入代码

这是我们的简单显示:

<section class="user-cloud">
  <div class="brands-container">
    <div class="brands-carousel">
      <picture>
        <source srcset="assets/images/s-customer-cloud1.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud1.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud2.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud2.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud3.png"
            media="(max-width: 766px)" />
        <img src="assets/images/customer-cloud3.png" />
      </picture>
      <picture>
        <source srcset="assets/images/s-customer-cloud4.png"
            media="(max-width: 766px)" />
        <img src="assets/images/s-customer-cloud4.png" />
      </picture>
    </div>
  </div>
</section>
Enter fullscreen mode Exit fullscreen mode

我们在移动设备上有四张图片,而在桌面上只有三张图片。为了使其响应式,我们使用了picture带有sourceimgset的标签。Img选择器不起作用,所以我们使用了picture。不知道为什么,但与其纠结于此,不如这样做更容易。这样就不用费力地x2 multiples计算元素在屏幕上的大小了。

然后我们将为容器添加一些漂亮的填充和设置。

重要提示max-width这里的宽度应始终与所有图片的宽度相同,因此 100% 表示整个图片的宽度:

.brands-container {
  /* all pictures should be the same size as this value. */
  max-width: 1050px;
  margin: auto;
  padding:0 1em;
  overflow: hidden;
}

.brands-carousel {
  position: relative;
  padding-left: 0;
  margin: 0;
  height: 200px;
  overflow: hidden;
}

.brands-carousel > div {
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

设置就是这样,比较简单,下面是重要的设置:

/* Each picture in the carousel is 100% of the parent. */
.brands-carousel > picture {
  width: 100%;
  position: absolute;
  top: 0;
  display: flex;
  justify-content: center;
  animation: carousel 20s linear infinite;

  /* It also starts off the screen until it is time. */
  transform: translateX(100%);
}
Enter fullscreen mode Exit fullscreen mode

first-picture(我暂时不讨论关键帧)
每张图片的设置都一样,需要 N 秒才能移动到屏幕上并停留在那里,直到下一张图片移动。桌面端计算有三张图片,所以每张图片在屏幕上停留的时间各占三分之一。

.brands-carousel > picture:nth-child(1) {
  animation-name: first-picture, carousel;
  animation-duration: 20s;
  animation-iteration-count: 1, infinite;
  animation-delay: 0s, 20s;
  transform: translateX(0%);
}
.brands-carousel > picture:nth-child(2) {
  animation-delay: Calc(20s * .33);
}
.brands-carousel > picture:nth-child(3) {
  animation-delay: Calc(20s * .66);
}
Enter fullscreen mode Exit fullscreen mode
/* The keyframes for desktop */
@keyframes first-picture {
  0% { transform: translateX(0%); }
  7.5%, 33% { transform: translateX(0); }
  40.5%, 100% { transform: translateX(-100%); }
}

@keyframes carousel {
  0% { transform: translateX(100%); }
  7.5%, 33% { transform: translateX(0); }
  40.5%, 100% { transform: translateX(-100%); }
}
Enter fullscreen mode Exit fullscreen mode

所以主要的关键帧是轮播。由于每张图片在舞台上停留的时间占1/3,它会占用20秒时间的7.5%,并停留在那里直到33%的时间结束,然后才移出。由于每张图片需要7.5%的时间进入舞台,所以它也需要7.5%的时间离开舞台
33% + 7.5% = 40.5

这几乎完全有效,除了一件事:在20秒的33%之前,没有图像完全显示。解决这个问题的方法是使用一个技巧,将第一幅图像显示两次。我们会在屏幕上显示它,直到它离开;同时,我们会在屏幕右侧显示它,直到它开始。然后,我们将第二个动画延迟一整轮。因此,我们需要first-picture关键帧,这样做效果很好。

/* The keyframes for mobile */
@keyframes first-picture-responsive {
  0% { transform: translateX(0%); }
  5.5%, 25% { transform: translateX(0); }
  30.5%, 100% { transform: translateX(-100%); }
}

@keyframes carousel-responsive {
  0% { transform: translateX(100%); }
  5.5%, 25% { transform: translateX(0); }
  30.5%, 100% { transform: translateX(-100%); }
}
Enter fullscreen mode Exit fullscreen mode

不要在桌面上显示第四张图片

.brands-carousel > picture:last-child {
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

在移动设备上,我们会做一些小的调整,将 3 张图片的显示时间从 20 秒改为 4 张图片的显示时间 27 秒,每张图片在舞台上显示的时间占 1/4。

@media screen and (max-width: 766px) {
  .brands-carousel > picture {
    animation: carousel-responsive 27s linear infinite;
  }

  .brands-carousel > picture:nth-child(1) {
    animation-name: first-picture-responsive, carousel-responsive;
    animation-duration: 27s;
    animation-iteration-count: 1, infinite;
    animation-delay: 0s, 27s;
  }

  .brands-carousel > picture:nth-child(2) {
    animation-delay: Calc(27s * .25);
  }
  .brands-carousel > picture:nth-child(3) {
    animation-delay: Calc(27s * .50);
  }
  .brands-carousel > picture:nth-child(4) {
    animation-delay: Calc(27s * .75);
    display: block;
  }
}
Enter fullscreen mode Exit fullscreen mode

完成

如果您想更改完整动画循环的时间,请将 替换20s为新的完整时间。要更改屏幕上过渡的时长,请将 减小7.5%为较小的值(并将 减小40.5%相同的量)。要进行任何其他更改(例如增加图像静止的时间长度),您需要基于总时间的 33% 进行计算,然后重新计算过渡百分比。

现在静态图像5.1s在屏幕上的占比是 7.5% 到 33%,也就是 20 秒的 25.5% ( )。如果您希望它6s在屏幕上显示而不减少过渡时间 ( )。计算完整动画的7.5% * 20s = 1.5s新总时间,然后计算新的过渡百分比,这样新的关键帧将是6 / .255 = 23.5s1.5s / 23.5s = 6.4%

/* # Updating all the 20s => 23.5s */
@keyframes carousel {
  0% { transform: translateX(100%); }
  6.4%, 33% { transform: translateX(0); }
  39.4%, 100% { transform: translateX(-100%); }
}
Enter fullscreen mode Exit fullscreen mode

就是这样。

这是代码的链接

文章来源:https://dev.to/wparad/making-an-infinite-css-carousel-2dek
PREV
我编写代码文档的 3 条规则
NEXT
VS Code 快捷键速查表🔥 - 提高工作效率🚀