Back

使用纯 CSS 构建流畅的轮播图

使用纯 CSS 构建流畅的轮播图

多年以来,创建轮播图意味着需要使用 JavaScript 库,如 Swiper 或 Glide。每个库都会为你的打包文件增加数千字节,引入依赖项,并需要仔细管理事件监听器和状态。但现代 CSS 已经悄然演进,能够原生处理轮播图——无需 JavaScript。

本文探讨如何使用 scroll-snap、实验性伪元素以及其他纯 CSS 技术构建高性能、可访问的 CSS 轮播图,这些技术不仅现在可用,而且在未来数年内仍将保持相关性。

核心要点

  • Scroll-snap 属性可将任何可滚动容器转换为流畅的轮播体验
  • Chrome 135+ 中的实验性伪元素支持无需 JavaScript 的原生导航控件
  • 纯 CSS 轮播图通过消除 JavaScript 解析和事件监听器来提升性能
  • 降级策略确保兼容性,同时为未来的浏览器特性做好准备

基础:Scroll Snap CSS

任何纯 CSS 轮播图的基石都是 scroll-snap 属性。它只需几行代码就能将可滚动容器转换为分页体验:

.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
}

.carousel-item {
  flex: 0 0 100%;
  scroll-snap-align: center;
}

这将创建一个水平轮播图,其中每个项目都会对齐到位。mandatory 关键字确保用户始终停留在完整的幻灯片上,而 scroll-behavior: smooth 则在项目之间添加流畅的过渡效果。

Scroll Snap CSS 在所有现代浏览器中都能工作,使其成为无 JavaScript 轮播图最可靠的基础。对于响应式设计,可以将其与 CSS Grid 结合使用,或调整 flex-basis 以在每个视图中显示多个项目:

.carousel-item {
  flex: 0 0 calc(33.333% - 1rem);
  margin: 0 0.5rem;
}

现代导航:实验性伪元素

Chrome 135+ 引入了可自动生成轮播控件的实验性伪元素。这些特性需要在 Chrome 标志中启用实验性 Web 平台功能。

::scroll-button 伪元素无需额外标记即可创建上一个/下一个按钮:

.carousel::scroll-button(inline-start),
.carousel::scroll-button(inline-end) {
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 1rem;
  border: none;
}

.carousel::scroll-button(inline-start)::before {
  content: "←";
}

.carousel::scroll-button(inline-end)::before {
  content: "→";
}

类似地,::scroll-marker 为每个可滚动部分生成分页指示点:

.carousel {
  scroll-marker-group: after;
}

.carousel-item::scroll-marker {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ccc;
}

.carousel-item::scroll-marker:target-current {
  background: #333;
}

请注意,这些伪元素是实验性的,其语法可能会发生变化。:target-current 伪类会在用户滚动时高亮显示活动标记。这些特性减少了 JavaScript 需求,同时提供原生的可访问性支持。

生产环境的降级策略

由于 scroll-button 和 scroll-marker 的浏览器支持有限,请使用 @supports 进行特性检测:

/* 降级导航 */
.carousel-nav {
  display: flex;
  gap: 0.5rem;
}

/* 当支持原生控件时隐藏降级方案 */
@supports (scroll-button-inline: both) {
  .carousel-nav {
    display: none;
  }
}

为了更广泛的兼容性,可以将 scroll-snap 与锚点链接结合用于导航:

<nav class="carousel-nav">
  <a href="#slide1">1</a>
  <a href="#slide2">2</a>
  <a href="#slide3">3</a>
</nav>

<div class="carousel">
  <div id="slide1" class="carousel-item">...</div>
  <div id="slide2" class="carousel-item">...</div>
  <div id="slide3" class="carousel-item">...</div>
</div>

无需 JavaScript 的 CSS 自动播放轮播图

创建 CSS 自动播放轮播图只需要关键帧动画:

@keyframes slide {
  0%, 20% { transform: translateX(0); }
  25%, 45% { transform: translateX(-100%); }
  50%, 70% { transform: translateX(-200%); }
  75%, 95% { transform: translateX(-300%); }
  100% { transform: translateX(0); }
}

.autoplay-carousel {
  display: flex;
  animation: slide 12s infinite;
}

.autoplay-carousel:hover {
  animation-play-state: paused;
}

这种技术工作可靠,但以简单性换取了用户控制。悬停时暂停可提高可用性,结合 prefers-reduced-motion 可以尊重可访问性偏好:

@media (prefers-reduced-motion: reduce) {
  .autoplay-carousel {
    animation: none;
  }
}

可访问性与性能

纯 CSS 轮播图在性能方面表现出色——无需 JavaScript 解析、无事件监听器、无布局抖动。浏览器的原生滚动自动处理触摸、键盘和鼠标输入。

为了确保可访问性:

  • Scroll-snap 提供流畅的滚动,但完整的键盘导航和可访问控件需要新的 ::scroll-button 和 ::scroll-marker 特性
  • 焦点指示器保持可见
  • 当 CSS 失效时内容仍然可访问
  • 触摸目标满足 44×44px 的最小尺寸

添加 ARIA 标签以改善屏幕阅读器体验:

<div class="carousel" role="region" aria-label="产品画廊">
  <div class="carousel-item" aria-label="第 1 张,共 3 张">...</div>
</div>

结论

现代 CSS 在大多数情况下已经消除了对 JavaScript 轮播库的需求。Scroll-snap 提供了当前的基础,而像 scroll-button 和 scroll-marker 这样的新兴特性预示着一个复杂 UI 组件无需 JavaScript 的未来。这些技术减少了打包体积,提升了性能,并简化了维护——这些好处会随着时间的推移而累积。

从生产网站的 scroll-snap 开始。在 Chrome 中尝试新的伪元素。最重要的是,当 20 行 CSS 就能实现相同结果时,质疑你是否真的需要那个 50KB 的轮播库。

常见问题

可以,scroll-snap 属性在所有现代浏览器中都有出色的支持。实验性伪元素只应在提供适当降级方案的情况下使用,因为它们目前仅在启用标志的 Chrome 135+ 中工作。

Scroll-snap 通过原生浏览器滚动自动支持触摸手势。用户可以在幻灯片之间自然地滑动,强制对齐点确保他们始终停留在完整的幻灯片上,无需额外代码。

CSS 轮播图在 JavaScript 被禁用时仍能完美工作,因为它们完全依赖原生 CSS 属性。用户仍然可以使用触摸、鼠标或键盘进行导航,使其比基于 JavaScript 的解决方案更具弹性。

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay