无限跑马灯

两排标签朝相反方向无缝滑动,悬停时暂停。

  • CSS
  • 布局
  • 循环
  • 收录于
  • 品牌设计
  • 网页设计
  • 动效
  • Next.js
  • 文案
  • SEO
  • 电商
  • 数据看板
  • 原型
  • 落地页
  • 设计系统

AI 提示词

用 CSS 在 React 中制作两排反向移动的无缝跑马灯。每一排在同一个 flex 轨道中把项目列表渲染两遍(第二份加 aria-hidden),并让轨道从 translateX(0) 线性无限动画到 translateX(-50%)(第一排 30 秒,第二排 36 秒反向),这样循环时不会跳动。轨道使用 gap,并设置与 gap 相同的 padding-right,让两半精确对齐。用 mask-image: linear-gradient(90deg, transparent, black 10%, black 90%, transparent) 淡化两侧边缘。悬停和 focus-within 时用 animation-play-state: paused 暂停动画。项目为圆角标签。在 prefers-reduced-motion 下停止动画,改为允许横向滚动。

源代码

Demo.tsx
'use client'

import s from './demo.module.css'

function Row({ items, reverse }: { items: string[]; reverse?: boolean }) {
  return (
    <div className={s.row}>
      <div className={reverse ? `${s.track} ${s.reverse}` : s.track}>
        {[0, 1].map((copy) => (
          <ul key={copy} className={s.list} aria-hidden={copy === 1 || undefined}>
            {items.map((t) => (
              <li key={t} className={s.tag}>
                {t}
              </li>
            ))}
          </ul>
        ))}
      </div>
    </div>
  )
}

export default function Marquee({ labels }: { labels: Record<string, string> }) {
  return (
    <div className={s.wrap}>
      <Row items={labels.row1.split('|')} />
      <Row items={labels.row2.split('|')} reverse />
    </div>
  )
}
demo.module.css
.wrap { display: grid; gap: 12px; width: 100%; }

.row {
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, black 10%, black 90%, transparent);
}

.track {
  display: flex;
  width: max-content;
  animation: slide 30s linear infinite;
}

.reverse { animation-duration: 36s; animation-direction: reverse; }
.row:hover .track, .row:focus-within .track { animation-play-state: paused; }

.list {
  display: flex;
  gap: 10px;
  margin: 0;
  padding: 0 10px 0 0;
  list-style: none;
}

.tag {
  padding: 8px 14px;
  border: 1px solid var(--stage-rule);
  border-radius: 999px;
  background: var(--stage-surface);
  color: var(--stage-ink);
  font: 500 var(--text-sm) / 1 var(--font-body);
  white-space: nowrap;
}

.reverse .tag:nth-child(odd) { border-color: var(--stage-accent); color: var(--stage-accent); }

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

@media (prefers-reduced-motion: reduce) {
  .track { animation: none; }
  .row { overflow-x: auto; }
}

投稿创意

看到想收录的动效或主题?简单描述一下,会打开一个预先填好的 GitHub Issue,确认后即可提交。

你想投稿的是?

需要 GitHub 账号,投稿内容会公开。