用mask-image可实现文字边缘真正贴合的渐隐效果,核心是裁剪而非叠加:mask-image: linear-gradient(to right, black 0%, black 85%, transparent 100%); -webkit-mask-image同写,black显示、transparent隐藏,过渡段控制柔化范围,适配任意背景且不阻点击。

用 mask-image 实现真正贴合文字的边缘渐隐
直接给文字加 background: linear-gradient 是无效的——color 不支持渐变,background-clip: text 在滚动容器里又容易错位或闪烁。最稳的方案是用 mask-image:它不是盖一层遮罩,而是“裁剪”内容本身,让文字天然在边缘淡出,不挡点击、不干扰滚动、适配任意背景色。
关键代码就两行:
mask-image: linear-gradient(to right, black 0%, black 85%, transparent 100%); -webkit-mask-image: linear-gradient(to right, black 0%, black 85%, transparent 100%);
其中 black 表示完全显示,transparent 表示完全隐藏,中间过渡段(85%→100%)就是柔化区。数值要按实际标签宽度微调:窄屏可缩到 black 80%, transparent 95%;若标签带图标或空隙大,可放宽至 black 90%, transparent 100%。
为什么不用伪元素 ::after 叠加渐变?
伪元素方案看似简单,但在真实横向滚动场景中容易翻车:
- 滚动时伪元素位置可能和内容不同步,尤其在快速滑动或 iOS Safari 下出现“遮罩漂移”
- 必须精确控制
width和right值,一旦标签动态增减或响应式重排,就得 JS 重新计算 - 遮罩层会挡住点击区域,除非额外加
pointer-events: none,但此时又无法响应 hover 效果 - 深色模式下需手动同步遮罩颜色,而
mask-image完全无视颜色,只管透不透
所以除非项目还在支持 IE 或极老安卓 WebView,否则别碰伪元素方案。
scroll-track-ref 不是必须的,但监听滚动状态得自己来
像 ant-design-mobile 的 ScrollMask 组件确实只靠一个 scrollTrackRef 就能自动显隐遮罩,但它本质是用 JS 监听 scrollLeft 和 scrollWidth 差值来判断是否溢出。纯 CSS 方案做不到这点——mask-image 一直生效,不会随滚动位置动态开关。
如果真需要“只在可滚动时才淡出”,得补一点轻量 JS:
- 监听容器的
scroll事件 - 用
element.scrollLeft > 0判断是否没到左边界 - 用
element.scrollLeft + element.clientWidth 判断是否没到右边界 - 根据结果切换一个类名,比如
has-overflow,再用 CSS 控制mask-image的有无
不过多数场景下,常驻淡出比“忽隐忽现”体验更自然,尤其对 Tab 栏这类高频切换控件。
移动端真机上容易被忽略的三个点
写完 CSS 后在 Chrome DevTools 里看着很顺,一上真机就出问题,通常卡在这三处:
-
mask-image在 iOS Safari 15.4 之前不支持百分比 stop 值,必须写成85%而非calc(100% - 15%),否则整条遮罩失效 - 容器若设了
transform(比如scale(0.99)用于防 iOS 字体放大),会禁用 mask 渲染,得改用zoom或其他方式 - 滚动容器父级若用了
contain: layout paint,可能截断 mask 绘制区域,临时去掉就能验证是不是它惹的祸
渐隐效果不是“做了就行”,而是“在所有滚动边界条件下都保持一致”。测试时一定要拖到最左、最右、快速来回滑,看淡出起始点是否始终对齐文字末端。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











