
通过 width: fit-content 替代固定 100% 宽度,并改用 left 与 transform: translateX() 组合控制位移,配合 JavaScript 动态计算动画时长,可实现真正无缝、匀速的无限文字滚动效果。
通过 `width: fit-content` 替代固定 `100%` 宽度,并改用 `left` 与 `transform: translatex()` 组合控制位移,配合 javascript 动态计算动画时长,可实现真正无缝、匀速的无限文字滚动效果。
要实现视觉上完全无缝的无限滚动文字(marquee),关键在于解决两个核心问题:
- 元素宽度误判:当 #marqueeText 设置 width: 100% 时,其宽度被强制拉伸为父容器宽(如 1120px),但实际文本内容仅约 150px——导致动画位移距离远超必要,出现长达数秒的“空白间隙”;
- 位移逻辑错配:原方案依赖 translate3d(100%, 0, 0) → translate3d(-100%, 0, 0),但 -100% 是相对于父容器计算的,而非文本自身宽度,造成退出与重入位置不匹配。
✅ 正确解法是:
- 将文本元素设为 width: fit-content,使其真实宽度 = 文本渲染宽度;
- 起始位置设为 left: 100%(即完全位于容器右侧外),transform: translateX(0);
- 结束位置设为 left: 0; transform: translateX(-100%) —— 此时 -100% 指自身宽度,确保文本完全左移至刚好消失于容器左边界;
- 动画自然循环时,left: 100% 状态会立即复位,实现“刚消失即重现在右”的无缝衔接。
以下是完整可运行代码:
<div class="d-none d-lg-flex row topmarquee mt-4">
<div class="marquee">
<p id="marqueeText" class="marqueeText mb-0">
This is a test website
</p>
</div>
</div>@keyframes marquee-animation {
from {
left: 100%;
transform: translateX(0);
}
to {
left: 0;
transform: translateX(-100%);
}
}
.topmarquee {
width: 100%;
border: 1px solid #000;
}
.topmarquee .marquee {
width: calc(100% - 200px);
position: relative;
overflow: hidden;
height: 31px;
}
.topmarquee .marquee #marqueeText {
display: block;
position: absolute;
top: 0;
margin: 0;
white-space: nowrap;
line-height: 31px;
width: fit-content; /* ✅ 关键:真实宽度 */
left: 100%; /* ✅ 起始:完全在右侧外 */
transform: translateX(0);
animation-name: marquee-animation;
animation-iteration-count: infinite;
animation-timing-function: linear;
}// 动态计算动画时长,保证像素级匀速(单位:ms/px)
const timePerPixel = 5; // 每像素滚动耗时(ms),越小越快
const containerWidth = 1120; // 容器可视宽度(px)
const text = document.getElementById('marqueeText');
const textWidth = text.offsetWidth; // ✅ 真实文本宽度(fit-content 后生效)
const distance = textWidth + containerWidth; // 总滚动距离 = 文本宽 + 容器宽
const duration = timePerPixel * distance;
text.style.animationDuration = `${duration}ms`;⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
- 务必在 DOM 加载完成且样式应用后执行 JS(推荐 window.addEventListener('load', ...) 或 document.addEventListener('DOMContentLoaded', ...)),否则 offsetWidth 可能读取为 0;
- 若文本内容动态变更(如 AJAX 更新),需重新调用 JS 计算并重置 animationDuration;
- fit-content 在旧版 Safari 中需加 -webkit-fit-content 前缀(兼容性要求高时建议后备方案);
- 避免在 .marquee 上设置 padding 或 border,否则需从 containerWidth 中扣除,否则位移精度将失准。
此方案彻底规避了“固定宽度导致位移冗余”的根本缺陷,结合精准的 JS 时长控制,实现了任意长度文本、恒定速度、零感知间隙的工业级无缝跑马灯效果。


















