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

如何在React中实现HTML文本元素无限循环水平滚动且无空白间隙

方案1:极简CSS无缝滚动方案(适配绝大多数动态文本场景)

  • 结构上每一行的滚动内容直接重复渲染两次相同的文本,利用两份完全一致的内容实现视觉无缝衔接
  • 修改CSS动画终点偏移为-50%,动画循环时不会出现视觉断层
  • 配套CSS代码:
/* 背景外层容器 */
.scroll-bg-container {
  overflow: hidden;
  width: 100vw;
  height: 100vh; /* 按需调整为实际需要的背景尺寸 */
}

/* 单行滚动文本容器 */
.scroll-row {
  white-space: nowrap;
  animation: scrollLeft 20s linear infinite;
  margin: 8px 0; /* 行间距按需调整 */
  font-size: 24px;
  color: rgba(0,0,0,0.1); /* 背景文本浅透效果按需调整 */
}

@keyframes scrollLeft {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
  • React组件示例:
const BackgroundText = ({ text, rowCount = 10 }) => {
  return (
    <div className="scroll-bg-container">
      {/* 生成指定行数的滚动文本 */}
      {Array.from({ length: rowCount }).map((_, rowIdx) => (
        <div key={rowIdx} className="scroll-row">
          {/* 每份内容重复两次,保证无缝衔接,空格用来避免两段文本直接贴在一起 */}
          <span>{text}&nbsp;&nbsp;</span>
          <span>{text}&nbsp;&nbsp;</span>
        </div>
      ))}
    </div>
  )
}

如果需要向右滚动,把动画终点的translateX(-50%)改成translateX(50%)即可,调整动画时长可以改变滚动速度。


方案2:动态计算重复份数(适配极短文本/超大容器场景)

如果文本长度很短、或者容器尺寸很大,两次重复不够覆盖容器宽度,可以通过动态计算需要重复的文本份数实现适配:

  • 用useRef获取单行文本的实际宽度和容器宽度,计算需要重复的最小份数,额外多2份作为滚动冗余
  • React实现示例:
import { useRef, useState, useEffect } from 'react';

const BackgroundText = ({ text, rowCount = 10 }) => {
  const containerRef = useRef(null);
  const sampleTextRef = useRef(null);
  const [repeatTimes, setRepeatTimes] = useState(2);

  // 文本变化时重新计算需要重复的次数
  useEffect(() => {
    if (!containerRef.current || !sampleTextRef.current) return;
    const containerWidth = containerRef.current.offsetWidth;
    const singleTextWidth = sampleTextRef.current.offsetWidth;
    // 最少保留2次重复,额外加2份冗余避免滚动漏空白
    const calculated = Math.ceil(containerWidth / singleTextWidth) + 2;
    setRepeatTimes(Math.max(calculated, 2));
  }, [text]);

  return (
    <div ref={containerRef} className="scroll-bg-container">
      {/* 预先渲染一份样本文本用来计算宽度,视觉上隐藏不占用布局 */}
      <span ref={sampleTextRef} style={{ position: 'absolute', visibility: 'hidden', whiteSpace: 'nowrap' }}>
        {text}&nbsp;&nbsp;
      </span>
      {Array.from({ length: rowCount }).map((_, rowIdx) => (
        <div key={rowIdx} className="scroll-row" style={{
          // 动态调整动画时长避免短文本滚动过快
          animationDuration: `${1.2 * repeatTimes}s`,
        }}>
          {Array.from({ length: repeatTimes }).map((_, textIdx) => (
            <span key={textIdx}>{text}&nbsp;&nbsp;</span>
          ))}
        </div>
      ))}
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:15:02