跨浏览器兼容 mask 需双写 -webkit-mask-image 和 mask-image 或内联 svg ;firefox 仅支持 data url 或同文档 id 引用,且 svg 必须全白;safari 15.4 前不支持标准 mask-image,需内联 mask 并设 maskunits="userspaceonuse"。

Firefox 和 Safari(旧版)对 mask 属性的支持不统一,不能只靠写一遍标准属性就指望它生效;真正能跨浏览器稳定工作的,只有两种路径:用 SVG <mask></mask> 内联定义,或严格双写 -webkit-mask-image + mask-image 并控制资源格式。
Firefox 不支持 mask-image: url() 加载外部 SVG
Firefox 会静默忽略 mask-image: url("mask.svg"),哪怕文件存在且可访问。它只接受两种形式:
-
mask-image: url("data:image/svg+xml;utf8,...")—— 必须是内联 data URL,且 SVG 内容中所有颜色必须为#fff(白色),背景透明; - 引用同文档内联的
<mask id="m"></mask>,即mask-image: url(#m)。
常见错误是把 Sketch/Figma 导出的 SVG 直接当遮罩用,结果全黑或全透——因为导出 SVG 常带 fill="#000" 或 opacity,而 mask 的亮度映射规则是:纯白 = 完全显示,纯黑 = 完全隐藏。
Safari 15.4 之前根本不认 mask-image 标准属性
在 iOS 15.4 / macOS Monterey 之前的 Safari 中,mask-image 声明会被完全跳过,无论是否加前缀。唯一可行的是:
- 用内联
<svg></svg>定义<mask></mask>,并设maskUnits="userSpaceOnUse"; - 目标元素通过
mask: url(#my-mask)引用,ID 必须在同一 HTML 文档内(不能跨 iframe 或 Shadow DOM); - 避免使用
mask-mode: luminance,Safari 对它的解析和 Chrome/Firefox 不一致,优先用默认 alpha 模式。
如果没设 maskUnits="userSpaceOnUse",SVG 遮罩会按相对坐标(0–1)缩放,导致圆角、矩形等形状严重错位。
Chrome/Safari/Firefox 三端同时兼容的写法
必须手动双写,且顺序固定:-webkit-mask-image 在前,mask-image 在后;不能依赖 Autoprefixer 补全,它对 mask 系列属性识别极不可靠。
- 对 PNG 遮罩:确保导出含 Alpha 通道,否则 WebKit 浏览器渲染为空白;
- 对 SVG 遮罩:同一张图,一个用 data URL 给 Firefox,一个用外部路径给 Safari/Chrome;
- 示例片段:
.masked {
-webkit-mask-image: url("mask.svg");
mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Ccircle cx='50' cy='50' r='40' fill='%23fff'/%3E%3C/svg%3E");
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-size: cover;
mask-size: cover;
}
注意:mask-size 和 mask-position 也必须成对声明,否则某些版本 Safari 会丢弃整条规则。
当 CSS 遮罩彻底失效时,用 SVG <mask></mask> 是唯一可靠 fallback
SVG 的 <mask></mask> 渲染由各浏览器 SVG 引擎执行,行为一致,且支持 mask-composite(如 subtract)等布尔运算,这是目前唯一能在 Chrome、Firefox、Safari 全平台精确实现“打孔”“交集”的方式。
- 不要用外部 SVG 文件定义
<mask></mask>,必须内联到 HTML 中; - 设
width/height覆盖目标元素最大可能尺寸(例如width="2000" height="2000"),避免裁剪; - 引用时用
mask: url(#my-mask),不是mask-image。
最容易被忽略的是:mask 是合成阶段操作,不影响 DOM 结构、不改变事件穿透区域。如果点击异常,问题不在 mask 本身,而在父容器的 overflow 或 transform 层叠上下文干扰了渲染管线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











