无缝滚动 Logo 墙
Infinite Logo Marquee
初级通用官网上「这些公司都在用我们」的那一排 Logo,一直缓缓往一个方向走,首尾相接看不出断点,两端淡入淡出,鼠标移上去就停下。只用 CSS 就能做,不需要任何轮播库。
你可能会说:「官网上合作客户的 Logo 能不能做成一排一直慢慢滚动、而且看不出从哪里重新开始的效果?」
效果预览一排 Logo 首尾相接地一直走
怎么做3 步做出来
- 1
把 Logo 列表复制一份
无缝的秘诀是:同一组 Logo 写两遍,排成一长条。动画走完一半时,第二份正好走到第一份原来的位置,这时跳回起点,肉眼看不出来。第二份加 aria-hidden,读屏软件就不会把每个 Logo 读两遍。
查看代码收起代码html
<div class="marquee"> <ul class="marquee__track"> <li><img src="/logos/cloudly.svg" alt="Cloudly"></li> <li><img src="/logos/nimbus.svg" alt="Nimbus"></li> <li><img src="/logos/stackr.svg" alt="Stackr"></li> <!-- 同一组再写一遍,供首尾衔接 --> <li aria-hidden="true"><img src="/logos/cloudly.svg" alt=""></li> <li aria-hidden="true"><img src="/logos/nimbus.svg" alt=""></li> <li aria-hidden="true"><img src="/logos/stackr.svg" alt=""></li> </ul> </div> - 2
平移一半宽度,无限循环
轨道宽度设为 max-content,动画从 0 平移到 -50%,线性、无限循环。有个容易出缝的细节:Logo 之间用 gap 隔开时,最后一个 Logo 后面没有间距,两份接起来就差了一个 gap,每圈会跳一下;给轨道加一个和 gap 相等的 padding-right 就严丝合缝了。两端渐隐用 mask-image 做,鼠标悬停时暂停。
查看代码收起代码css
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); } .marquee__track { display: flex; gap: 48px; padding-right: 48px; /* 和 gap 相等,首尾衔接不跳 */ width: max-content; animation: marquee 20s linear infinite; } .marquee:hover .marquee__track { animation-play-state: paused; } @keyframes marquee { to { transform: translateX(-50%); } } - 3
减少动效时停下来
开启减少动效的用户,给他们一排静止、可换行的 Logo,并把复制出来的那一份藏起来。
查看代码收起代码css
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; flex-wrap: wrap; justify-content: center; width: auto; } .marquee__track [aria-hidden="true"] { display: none; } }
适合放在哪
适合用
- 官网首页「合作客户」「媒体报道」的 Logo 展示。
- 落地页里滚动的用户评价短句或标签云。
- 活动页顶部一条滚动的公告或优惠信息(内容要短,读得过来)。
不适合用
- 需要用户逐条阅读、点击的重要信息,别放进滚动条;用户还没读完就走了,改用静态列表。
- Logo 只有两三个时,别硬做成滚动;一排静态摆放更体面。
- 同一页别放好几条滚动带;满屏都在动会让人分心。
让 AI 帮你做复制给 AI Agent 直接用
请把【需要滚动展示的一组内容,如:首页「合作客户」区域的 Logo 列表】做成无缝滚动。先阅读这个区域的组件和样式写法,确认 Logo 数据从哪里来、项目里有没有已用的轮播库(这个效果不需要新增依赖)。要求:同一组内容渲染两遍,第二份加 aria-hidden;轨道 width: max-content,用 CSS 动画从 0 平移到 -50%,线性无限循环,速度约 20~40 秒一圈;用 gap 时给轨道加等宽的 padding-right,保证首尾不跳;两端用 mask-image 渐隐;悬停暂停;开启减少动效时停止滚动并隐藏复制的那一份。不改无关代码。最后说明怎样验证:盯着衔接处看一整圈不跳动。