直接用 mask-image: linear-gradient() 会失效,因浏览器支持不统一:safari 将 transparent 视为 #000,firefox 忽略声明,chrome/edge 需同时写 -webkit-mask-image 且无像素级控制,且渐变无法实现文字轮廓、镂空或抗锯齿剪裁。

为什么直接用 mask-image: linear-gradient() 会失效
因为浏览器对渐变遮罩的支持完全不统一:Safari 把 transparent 当作 #000(全显),Firefox 直接忽略整条声明,Chrome/Edge 必须同时写 -webkit-mask-image 才生效,且无像素级控制能力。渐变本身也无法表达文字轮廓、镂空或抗锯齿边缘——它只是软边过渡,不是“剪裁”。
用内联 SVG 作为 mask-image 的可靠写法
这是目前唯一能兼顾精度、可控性和多浏览器支持的方案,关键在写法细节:
- SVG 必须内联进 HTML 的
<defs></defs>中,用url(#my-mask)引用;外链 SVG 易触发 CORS,跨域就挂 -
<mask></mask>内只用纯灰度:白色#fff= 显示,黑色#000= 隐藏,灰色 = 半透;别加fill-opacity或opacity - 不要给 SVG 根元素设
width/height;靠 CSS 的mask-size: 100% 100%让它随容器缩放 - 文字遮罩务必用
text-anchor和dominant-baseline居中,否则偏移不可控
示例片段(可直接复制):
<svg width="0" height="0"><defs><mask id="text-mask"><rect width="100%" height="100%" fill="white"></rect><text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" font-size="48" fill="black">MASK</text></mask></defs></svg><div class="masked" style=" background-image: url(photo.jpg); -webkit-mask-image: url(#text-mask); mask-image: url(#text-mask); mask-size: 100% 100%; "></div>
用 PNG 遮罩图时三个必设的 CSS 属性
PNG 方案适合已有 Alpha 图的场景,但漏设任意一项就会出错:
-
mask-repeat: no-repeat—— 默认是repeat,不设就平铺成马赛克 -
mask-size: cover或100% 100%—— 不设就按 PNG 原尺寸渲染,小图拉伸失真 -
mask-position: center—— 不设可能偏左上角,尤其当容器有 padding 或 margin 时
另外注意:Photoshop 导出 PNG 遮罩图时,必须关掉“消除锯齿”和“对齐像素”,否则边缘灰阶不准,导致半透区域意外显示或隐藏。
兼容性兜底与渐进增强策略
没有一种写法能在所有浏览器里 100% 工作,所以得有 fallback:
- 对不支持
mask-image的旧浏览器(如 IE、老 Android WebView),用clip-path: polygon()做简单几何裁切,或直接降级为圆角+阴影 - 不要依赖
mask-mode或mask-composite等新属性,它们在 Safari 17.5 以下、Firefox 127 以下基本无效 - 若需动态切换遮罩,避免用 JS 改
mask-image的 URL;改用 class 切换 + CSS 变量(--mask)更稳定
真正难的不是写出遮罩,而是让同一张图在 Safari/Firefox/Chrome 里看起来一致——这要求你放弃“写一次跑 everywhere”的幻想,接受 SVG 内联 + 显式尺寸控制 + 严格灰度定义这一套组合拳。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











