You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Next.js + Tailwind CSS无限轮播动画闪烁问题修复咨询

解决Next.js + Tailwind CSS无限轮播循环后闪烁问题

我在使用React(基于Next.js)和Tailwind CSS开发无限轮播组件时,发现Logo完成一轮滚动循环后,动画会出现闪烁现象。以下是我当前的代码:

原TSX代码

import * as React from "react";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import Photo from "../../public/Profile-Picture.jpg";
import { Icon } from "@iconify/react";

export default function Home() {
  const images = ["skill-icons:javascript", "skill-icons:typescript"];

  return (
    <div className="xl:container mx-auto ">
      <div className=" flex items-center min-h-screen justify-center">
        <div className="w-[200%] h-20 border-t border-b border-gray-600 overflow-hidden relative">
          <div className="w-[200%] flex items-center h-20 justify-around absolute left-0 gap-20 animate">
            {images.map((i,index) => {
              return (
                <div className="flex justify-center items-start w-[20rem]">
                  <img key={index} src={i} />
                </div>
              );
            })}
            {images.map((i) => {
              return (
                <div className="flex justify-center items-start w-[20rem]">
                  <img key={index} src={i} />
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
      );
}

原CSS代码

@keyframes scroll {
  0% {
    left: 0;
  }
  100% {
    left: -100%;
  }
}

.animate {
  animation: scroll 5s linear infinite;
}

问题分析

闪烁的核心原因有两个:

  1. 动画位置突变:当前动画从left: 0滚动到left: -100%,循环重置时元素会瞬间从-100%跳回0,造成视觉断层。
  2. 重复元素key冲突:第二个images.map未生成独立的key,复用了第一个循环的index值,导致React虚拟DOM渲染异常,加剧闪烁。

修复方案

1. 修正key值

为第二份重复内容生成独立key,避免React渲染混淆。

2. 调整动画逻辑

将滚动容器宽度设为200%(包含两份相同内容),动画目标位置改为left: -50%,此时第二份内容会刚好衔接第一份的起始位置,消除跳变。

3. 启用硬件加速

添加transform: translateZ(0)触发浏览器硬件加速,提升动画流畅度。


修改后的TSX代码

import * as React from "react";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import Photo from "../../public/Profile-Picture.jpg";
import { Icon } from "@iconify/react";

export default function Home() {
  const images = ["skill-icons:javascript", "skill-icons:typescript"];

  return (
    <div className="xl:container mx-auto">
      <div className="flex items-center min-h-screen justify-center">
        {/* 外层容器设为单轮内容宽度,overflow隐藏 */}
        <div className="w-full max-w-5xl h-20 border-t border-b border-gray-600 overflow-hidden relative">
          {/* 滚动容器宽度设为200%,容纳两份内容 */}
          <div className="w-[200%] flex items-center h-20 justify-around absolute left-0 gap-20 animate-scroll">
            {images.map((i, index) => (
              <div key={`primary-${index}`} className="flex justify-center items-start w-[20rem]">
                <img src={i} alt={`skill-icon-${index}`} />
              </div>
            ))}
            {images.map((i, index) => (
              {/* 生成独立key,避免与第一份内容冲突 */}
              <div key={`duplicate-${index}`} className="flex justify-center items-start w-[20rem]">
                <img src={i} alt={`skill-icon-duplicate-${index}`} />
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

修改后的CSS代码

@keyframes scroll {
  0% {
    left: 0;
  }
  /* 滚动到-50%,第二份内容刚好衔接第一份起始位置 */
  100% {
    left: -50%;
  }
}

.animate-scroll {
  animation: scroll 5s linear infinite;
  /* 触发硬件加速,减少动画卡顿 */
  transform: translateZ(0);
}

内容的提问来源于stack exchange,提问作者SpicyyRiice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:13:18