
通过 javascript 动态检测元素是否溢出容器,并仅对溢出文本添加 hover 滚动动画,可精准控制 css 动画的启用时机,避免短文本误触发滚动。
在构建响应式 ui 组件(如标签芯片、状态徽章)时,常需为超长文本添加水平滚动效果以提升可读性。但若对所有文本无差别应用 @keyframes 滚动动画,会导致短文本在悬停时产生无效位移,破坏用户体验。纯 css 无法可靠判断内容是否溢出(:has() 伪类暂不支持 overflow 相关条件,且 scrollWidth > clientWidth 无对应 CSS 状态),因此需借助轻量 javaScript 实现智能判定。
✅ 推荐实现方案(js + CSS)
核心思路:在 dom 加载后,遍历目标元素,比较其 scrollWidth(实际内容宽度)与 clientWidth(可视区域宽度),仅当内容真正溢出时,动态添加可触发动画的类名。
// 等待 DOM 就绪后执行 document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.chip-value').forEach(el => { // 关键判断:scrollWidth > clientWidth 表示内容溢出 if (el.scrollWidth > el.clientWidth) { el.classlist.add('scrolled'); } }); });
⚠️ 注意:使用 scrollWidth > clientWidth 比 offsetWidth > 400 更健壮——它基于实际渲染尺寸,兼容不同容器宽度、字体缩放及响应式布局,无需硬编码像素值。
? 对应 CSS 动画定义
.chip-container { max-width: 400px; height: 32px; white-space: nowrap; overflow: hidden; background-color: #666; color: white; border-radius: 16px; display: inline-flex; align-items: center; padding: 0 5px; } .chip-value { display: inline-block; margin: 0 5px; text-overflow: clip; /* 防止省略号干扰滚动 */ /* 确保内容不换行、不压缩 */ white-space: nowrap; overflow: hidden; } /* 仅当 .scrolled 类存在时,悬停才启动动画 */ .scrolled:hover { animation: scroll-rtl 15s linear infinite; } @keyframes scroll-rtl { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } }
? 进阶优化建议
- 性能友好:使用 infinite 而非 forwards,避免动画结束后卡在末尾位置;若需暂停效果,可配合 animation-play-state: paused。
- 响应式重检:窗口大小变化时(如移动端横竖屏切换),可监听 resize 事件并重新校验溢出状态(注意防抖)。
- 无障碍友好:为滚动文本添加 aria-live=”polite” 或提供“暂停动画”按钮,满足 WCAG 标准。
此方案兼顾语义清晰、逻辑严谨与生产可用性,是当前实现「按需滚动」最成熟可靠的实践方式。