mask-image比background-clip:text更适合“由浅入深”扫光,因其作为独立遮罩层可自由定义透明梯度并滑动,实现“不透明区逐渐覆盖文字”的物理感光效,配合mask-position动画与Safari兼容写法(双前缀+显式mask-repeat)及三段渐变、贝塞尔曲线调参,达成自然扫光效果。

直接用 mask-image 做文字“由浅入深”的扫光过渡,本质是控制遮罩的透明度渐变 + 位移动画,但必须注意:这不是纯背景色动画,不能靠 background-position 拉渐变,得靠 mask-position 在扩展后的遮罩画布上滑动。
为什么 mask-image 比 background-clip:text 更适合“由浅入深”扫光?
因为 background-clip: text 只能裁剪已有背景,扫光效果受限于背景图尺寸和位移逻辑;而 mask-image 是独立遮罩层,你可以自由定义遮罩本身的透明梯度(比如从 0% 透明 → 100% 不透明),再配合 mask-position 移动它,就能实现“光从弱到强扫过文字”的物理感。
常见错误是把扫光理解成“亮色掠过”,其实更准的思路是:“不透明区域逐渐覆盖文字”——遮罩越不透明,文字越显现,视觉上就是“光越来越强”。
- 遮罩用
linear-gradient(to right, transparent, #000):左边全透(文字不可见),右边全黑(文字完全显示) - 遮罩尺寸设为
mask-size: 200% 100%,给动画留出横向移动空间 - 初始位置
mask-position: -100% 0,让全透区对齐文字左边缘 - 动画终点
mask-position: 0 0,此时全黑区刚好覆盖全文本
关键 CSS 写法与 Safari 兼容性处理
截至 2026 年底,Safari(尤其是 iOS 17 及更早)仍不支持无前缀的 mask-image,Chrome 和 Firefox 已原生支持,但漏掉 -webkit-mask-image 就会在 Safari 下彻底失效。
立即学习“前端免费学习笔记(深入)”;
必须同时写两行,且不能用 mask 简写(会重置 mask-size、mask-position 等):
h1 {
-webkit-mask-image: linear-gradient(to right, transparent, #000);
mask-image: linear-gradient(to right, transparent, #000);
-webkit-mask-size: 200% 100%;
mask-size: 200% 100%;
-webkit-mask-position: -100% 0;
mask-position: -100% 0;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
animation: shineIn 2.5s ease-out forwards;
}
动画部分:
@keyframes shineIn {
to {
-webkit-mask-position: 0 0;
mask-position: 0 0;
}
}
- 别用
rgba(0,0,0,0)当透明色,某些旧版 Safari 会当黑,一律用transparent - 避免多层渐变或
image()函数,Safari 对这些支持极弱 -
mask-repeat: no-repeat必须显式声明,否则默认平铺会破坏单次扫光逻辑
怎么让“由浅入深”更自然?调参要点
“浅→深”不是线性变亮,而是要有起始缓入、中段加速、末端趋稳的节奏。靠纯 ease-out 不够,建议微调渐变断点和动画曲线:
- 遮罩渐变改用三段式:
linear-gradient(to right, transparent 0%, #000 30%, #000 100%),让不透明区提前开始,避免开头“突然亮起” - 动画用
cubic-bezier(0.16, 1, 0.3, 1)替代ease-out,延长加速段,更贴合人眼感知 - 如果文字较长,可把
mask-size调到300% 100%,再配mask-position: -200% 0 → 0 0,避免扫光过快“一闪而过” - 低端设备慎用:mask 动画在 iOS 16 以下或低端安卓机上易掉帧,可加
@supports (mask-image: none) { ... }降级为text-shadow模拟
真正难的不是写出来,而是让扫光停在“刚好够亮、不刺眼、不突兀”的那一帧——这需要反复调 mask-position 终点值和渐变断点百分比,而不是依赖预设动画时长。


















