Skip to content

CSS 实现无限滚动效果

更新: 2024/6/1 字数: 0 字 时长: 0 分钟

🔈 前言:无限滚动是一种常见的 UI 效果,常用于展示标签、图片轮播等场景。本文将介绍如何使用 CSS 和少量 JavaScript 实现平滑的无限滚动效果。

基本原理

无限滚动的核心原理是通过 CSS 动画移动元素,并通过复制内容来实现视觉上的无缝衔接。当内容滚动到一定位置时,通过位移动画让内容看起来是无限循环 的。

实现代码

首先,我们需要创建 HTML 结构(这里使用了 vue3 + ts + setup 和 tailwind css, 请根据实际情况进行修改):

html
<div class="swiper py-4 overflow-hidden">
  <div
    ref="swiperWrapper"
    @mouseenter="iaPlay = false"
    @mouseleave="iaPlay = true"
    class="swiper-wrapper w-max flex gap-2"
    :style="{ animationPlayState: iaPlay ? 'running' : 'paused' }"
    :data-animated="true"
  >
    <div class="swiper-container flex-1 flex gap-2" v-for="i in 2" :key="i">
      <!-- 这里复制了一份内容,方便做无缝衔接 -->
      <div class="swiper-item rounded-3xl px-5 py-2" v-for="(tag, index) in allTags" :key="index">
        <!-- 这里就是需要滚动的元素 -->
        <a class="tag-item whitespace-nowrap text-base cursor-pointer"> # {{ tag }} </a>
      </div>
    </div>
  </div>
</div>

然后,添加 CSS 样式实现动画效果:

css
.swiper-wrapper[data-animated="true"] {
  animation: scroll 10s linear infinite;
}

@keyframes scroll {
  to {
    transform: translateX(-50%);
  }
}

最后,添加 JavaScript 控制动画的播放和暂停:

javascript
const swiperWrapper = ref<HTMLElement>(); // 获取swiperWrapper元素(获取dom)
const iaPlay = ref<boolean>(true); // swiper是否播放

实现要点解析

  1. 内容复制:通过v-for="i in 2"复制一份完全相同的内容,确保滚动时有足够的内容可以衔接。

  2. 动画控制

    • 使用 CSS 动画animation: scroll 10s linear infinite实现无限循环
    • 动画时间可以根据内容长度调整,这里使用 10 秒
    • linear确保匀速滚动,提供更平滑的视觉体验
  3. 用户交互

    • 当鼠标悬停时(@mouseenter="iaPlay = false"),暂停滚动
    • 当鼠标离开时(@mouseleave="iaPlay = true"),恢复滚动
    • 通过:data-animated="true"作为一个标记,用于控制动画状态
  4. 关键动画技巧

    • transform: translateX(-50%)使内容移动自身宽度的一半
    • 由于我们复制了一份内容,当第一份内容完全滚出时,第二份内容正好完全滚入,视觉上形成无缝衔接

适用场景

这种无限滚动效果适用于:

  • 标签云展示
  • 图片轮播
  • 新闻滚动条
  • 产品展示轮播

性能优化

为了提高性能,可以考虑以下几点:

  • 使用transform而非left/top属性进行动画,利用 GPU 加速
  • 为动画元素添加will-change: transform提示浏览器做优化准备
  • 根据实际需求调整动画速度和内容数量

兼容性处理

对于不支持 CSS 动画的旧浏览器,可以使用 JavaScript 实现类似效果:

javascript
// 兼容性处理示例
if (!CSS.supports("animation", "scroll 10s linear infinite")) {
  // 使用JavaScript实现滚动效果
  const scrollElement = () => {
    const wrapper = document.querySelector(".swiper-wrapper");
    let position = 0;

    setInterval(() => {
      position -= 1;
      if (position <= -50) {
        position = 0;
      }
      wrapper.style.transform = `translateX(${position}%)`;
    }, 100);
  };

  scrollElement();
}

总结

无限滚动是一种优雅的内容展示方式,通过 CSS 动画和简单的 JavaScript 交互,我们可以轻松实现这一效果。关键在于理解动画原理和内容复制的技巧,以 及如何通过用户交互来控制动画状态。