
本文详解如何通过 CSS 动画与精确宽度控制,构建无间隙、无卡顿的无缝滚动字幕效果,解决常见 marquee 中因内容重复错位导致的空白或跳跃问题。
本文详解如何通过 css 动画与精确宽度控制,构建无间隙、无卡顿的无缝滚动字幕效果,解决常见 `marquee` 中因内容重复错位导致的空白或跳跃问题。
传统基于 left 位移 + 百分比动画的 Marquee 实现(如 left: 0% → left: -100%)在多段文本拼接时极易出现视觉断层——这是因为百分比位移依赖父容器宽度,而子元素实际总宽往往不等于 100vw,导致动画终点无法精准对齐起点,产生“抽帧式”跳变或留白。
核心原理:无缝滚动 = 单次位移距离 ≡ 单个滚动单元的精确物理宽度
✅ 正确做法是:
- 将每组待滚动内容(含间隔符)封装为独立 .marquee-item;
- 使用 transform: translateX() 替代 left,确保硬件加速且渲染稳定;
- 动画位移值设为该单元的固定像素宽度(如 274px),而非百分比;
- 移除冗余的 width: 100vw 和 overflow: hidden 等干扰样式,让布局由内容自然驱动。
以下是精简可靠的实现代码:
立即学习“前端免费学习笔记(深入)”;
<div class="marquee">
<div class="marquee-in">
<div class="marquee-item">
<p class="marq">Hello it's me Mario</p>
<p class="asterisk marq">...</p>
</div>
<div class="marquee-item">
<p class="marq">Welcome to the CSS Marquee</p>
<p class="asterisk marq">...</p>
</div>
<!-- 可重复添加多个 item -->
</div>
</div>.marquee {
width: 100vw;
height: 50px;
overflow: hidden;
position: relative;
}
.marquee-in {
display: flex;
white-space: nowrap;
animation: trans 8s linear infinite;
}
.marquee-item {
display: inline-flex;
align-items: center;
/* 关键:此处需设置为实际测量宽度(示例中为 274px) */
/* 开发时建议用 JS 动态计算或 CSS `ch`/`em` 配合字体度量 */
}
.marq {
font-family: monospace;
font-weight: 900;
text-transform: uppercase;
font-size: 20px;
margin: 0;
padding: 0 12px; /* 间距统一由 padding 控制 */
}
.asterisk {
font-size: 24px;
margin: 0;
}
@keyframes trans {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-274px); /* 必须等于 .marquee-item 的 offsetWidth */
}
}? 注意事项与优化建议:
- 宽度必须精确:274px 是示例值,实际应通过浏览器开发者工具测量 .marquee-item 的 offsetWidth,或使用 getBoundingClientRect() 动态计算并注入 CSS 变量;
- 避免 inline-block 布局塌陷:.marquee-item 使用 display: inline-flex 或 flex 更可控,消除默认行内元素间的空白间隙;
- 响应式适配:若需适配不同屏幕,可结合 clamp() 设置字体大小,并用 calc() 动态推导位移值,或改用 @container 查询(现代浏览器);
- 性能优先:始终使用 transform + will-change: transform 触发 GPU 加速,禁用 left/top 等触发重排的属性;
- 无障碍补充:为满足 WCAG,建议添加 aria-live="polite" 及暂停动画的交互控件(如 hover 暂停)。
最终效果是平滑、连续、无闪烁的无限滚动——每个 .marquee-item 从右边界进入,完整划过视口后,下一个立即无缝衔接,真正实现「丝滑工业级」字幕体验。











