用 mask-image 实现图片渐变淡出,必须放弃 transparent 和 rgba(),只用纯灰度值(#000、#fff、#808080),并为 Safari 加 -webkit-mask-image,Firefox 则必须换 SVG 方案——否则在部分浏览器里会全显或全黑。

直接说结论:用 mask-image 实现图片渐变淡出,必须放弃 transparent 和 rgba(),只用纯灰度值(#000、#fff、#808080),并为 Safari 加 -webkit-mask-image,Firefox 则必须换 SVG 方案——否则在部分浏览器里会全显或全黑。
为什么 mask-image: linear-gradient(to bottom, black, transparent) 在 Safari 里失效
Safari(15.4+)解析遮罩时只认 luminance(亮度),transparent 不是颜色值,会被强制转成 #000(全显),结果整个图片都露出来,毫无淡出效果。更糟的是,它不报错、不警告,只是静默失效。
- 正确写法只能是:
mask-image: linear-gradient(to bottom, #000, #fff)或linear-gradient(to bottom, #000, #808080) -
#000表示完全可见,#fff表示完全隐藏,中间灰阶控制过渡强度 - 别用
black/white别名——Safari 对别名解析不稳定,#000才真正可靠
Firefox 完全不支持渐变值,怎么办
截至 2026 年中,Firefox 仍把 mask-image: linear-gradient(...) 当作无效声明直接忽略,等同于没写。这不是 bug,是未实现特性。
- 唯一兼容方案是改用内联 SVG:
mask-image: url("data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><mask id="m"><lineargradient y2="1"><stop offset="0" stop-color="black"></stop><stop offset="1" stop-color="white"></stop></lineargradient></mask></svg>#m") - SVG 中必须明确写
stop-color="black",不能写fill="black"或省略 - 记得加
#m锚点,否则 Firefox 无法定位到<mask>元素
Chrome/Edge 必须加前缀才能动起来
新版 Chrome/Edge(Blink 内核)对标准 mask-image 支持不完整,只写 mask-image 常常没反应,必须显式加 -webkit-mask-image 才能触发渲染。
立即学习“前端免费学习笔记(深入)”;
- 实际要这样写才稳:
-webkit-mask-image: linear-gradient(to bottom, #000, #fff); mask-image: linear-gradient(to bottom, #000, #fff);
- 别只依赖
mask简写——它会漏掉mask-mode: luminance等关键默认行为 -
mask-repeat: no-repeat和mask-size: 100% 100%也得手动设,否则可能平铺或缩放错位
淡出方向控制:只改 linear-gradient 方向不够
想让图片从右往左“揭开”,不能只把渐变改成 to left。因为遮罩的起始位置由 mask-position 控制,默认居中,所以动画永远从中部展开。
- 要真正实现“从右开始淡出”,三者缺一不可:
-webkit-mask-image: linear-gradient(to left, #000, #fff); mask-image: linear-gradient(to left, #000, #fff); mask-position: right;
- 配合
mask-size: 0% 100%→100% 100%的动画,才能让遮罩从右向左扩展 - Safari 对
transform+mask组合敏感,动画中尽量避免给 masked 元素加transform,改用父容器位移
最容易被忽略的一点:mask-image 生效的前提是元素有「可绘制内容」。空 <div>、display: none、或父级 overflow: hidden 裁掉边界,都会导致蒙版完全不可见——而控制台不会提示任何错误。


















