mask-image单独用无光感,因其仅为裁切工具,不控制亮度/柔边;需叠加linear-gradient光束、mask-position扫动动画及opacity+will-change GPU加速三件套才成真流光。

为什么 mask-image 单独写在按钮上没光感
因为 mask-image 本质是“裁切遮罩”,不是“发光源”——它只决定哪些像素能透出来,对亮度、渐变、边缘柔化完全无影响。常见错误是只加 mask-position 动画,结果光条像刀片划过,生硬卡顿,且 Safari 下不加 -webkit-mask-image 前缀直接失效。
- 漏掉
-webkit-mask-image,Chrome/Safari 渲染为空白 -
mask-size没设,光束太细看不出扫动,太宽又像糊了一块灰 - 用 PNG/SVG 当 mask 源,加载延迟 + 缩放失真,hover 触发时明显滞后
- 没配
opacity动画和will-change: mask-position,动画掉帧严重
button:hover 里必须写的三件套
流光扫过效果不是靠一个属性撑起来的,而是三个层叠动作同步触发:
-
mask-image: linear-gradient(90deg, transparent, #000, transparent)—— 光束核心,中间必须是纯黑(#000),只有非透明区才显示内容 -
animation: sweep 1.4s ease-out forwards配合@keyframes sweep { 0% { -webkit-mask-position: -100% 0; } 100% { -webkit-mask-position: 200% 0; } }—— 控制光从左到右完整扫过,百分比单位适配不同按钮宽度 -
opacity动画叠加(比如从 0 → 1 → 0),且必须加will-change: opacity, -webkit-mask-position或transform: translateZ(0)强制 GPU 加速,否则 Safari 和旧 Chrome 会卡
定位相关坑:absolute + transform 不如直接用 mask-position
有人试图用伪元素 ::after 绝对定位+平移模拟扫光,结果发现光带和按钮边缘错位、缩放后偏移、多行按钮失效。mask 的优势正在于它天然贴合内容轮廓——只要按钮文字是 inline-block 或 block,光就一定沿着文字或背景形状走。
- 别给按钮设
display: inline,mask 对 inline 元素渲染不可靠,尤其中文易折行导致光条截断 - 不用
position: absolute+transform: translateX()模拟扫光,那是退化方案,性能差、控制难、无法响应字体大小变化 - 如果按钮有圆角或不规则边框,mask 仍能精准跟随;而伪元素方案需额外计算 clip-path 或反复调 margin
兼容性收尾:Firefox 和低版本 Chrome 怎么降级
Firefox 目前仍不支持 mask-image(仅实验性开启),所以必须提供 fallback:
立即学习“前端免费学习笔记(深入)”;
- 默认状态不写任何 mask 相关样式,避免无意义渲染开销
- 只在
button:hover里写-webkit-mask-image和配套动画,Safari/Chrome 走 mask 路径 - Firefox 用户看到的是基础
box-shadow或background-color变化,不影响功能 - 若需全浏览器一致光效,改用
background: linear-gradient+background-size/background-position动画,但注意:它只能扫过背景,无法“切”在文字轮廓上
真正难的不是写出第一版效果,而是让光束宽度、扫速、起止位置在不同字号、不同容器尺寸下都自然——这些细节得靠 % 单位 + forwards + will-change 组合压住,少一个就容易闪、跳、卡。


















