svg 配合 可实现支持 alpha 通道的精准透明度渐变遮罩,原理是依据蒙版内图形亮度(白=全显,黑=全隐,灰=半透)映射不透明度,比 css mask-image 兼容性更好、控制更精细。

直接用 <mask></mask> 配合 <lineargradient></lineargradient> 就能实现真正支持 alpha 通道的透明度渐变遮罩,比 CSS 的 mask-image 更可控、兼容性更好,尤其适合需要精细控制边缘半透或响应式缩放的场景。
SVG <mask></mask> 的亮度映射规则必须记牢
蒙版内图形的亮度(Luminance)决定目标元素对应位置的不透明度——不是“颜色”,而是“可见程度”:
-
#fff(纯白)= 完全显示 -
#000(纯黑)= 完全隐藏 - 灰色值(如
#808080)= 半透明,按亮度线性插值
常见错误是把蒙版当成普通绘图:比如用 transparent 填充 <rect></rect>,但 SVG <mask></mask> 不解析 alpha 通道,transparent 被当作黑色处理,整块就消失了。必须用灰阶色值或渐变明确表达明暗。
怎么写一个从左到右淡出的 SVG mask
核心是定义一个水平方向的灰阶渐变,并用它填充一个覆盖全区域的 <rect></rect>:
<svg width="0" height="0"><defs><mask id="fadeMask"><lineargradient id="fadeGrad" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" stop-color="#fff"></stop><stop offset="100%" stop-color="#000"></stop></lineargradient><rect width="100%" height="100%" fill="url(#fadeGrad)"></rect></mask></defs></svg>
关键点:
-
<svg></svg>设为width="0" height="0"即可隐藏,不影响布局 -
<mask></mask>必须放在<defs></defs>内,否则无法被引用 - 渐变方向由
x1/y1/x2/y2控制:垂直淡出就改y1="0" y2="1";中心羽化则换用<radialgradient></radialgradient>
如何把 mask 应用到 HTML 元素上
对 HTML 元素(如 <div>、<code><img>)应用 SVG mask,靠的是 CSS 的 mask 属性(注意不是 mask-image):
div.faded {
-webkit-mask: url(#fadeMask);
mask: url(#fadeMask);
}
但有三个硬性前提:
- 目标元素必须有明确宽高(例如
width: 300px; height: 200px;),否则蒙版坐标系会失准 - 若元素是响应式的(如
width: 100%),需确保其父容器尺寸稳定,或改用mask-size: 100% 100%显式拉伸 - Safari 旧版本(iOS 15.4 之前)不支持
mask: url()直接引用内联 SVG,此时只能退回到mask-image: url(data:image/svg+xml,...)编码方式
容易被忽略的坑:mask 不作用于子元素的定位上下文
很多人想用 <mask></mask> 实现“只遮罩图片、不遮罩上面的文字”,结果发现文字也被裁掉了——这是因为 mask 作用于整个渲染盒(rendering box),包括背景、边框、内容和所有子元素。
如果你需要分层控制,唯一办法是拆开 DOM 结构:
- 把图片单独包一层,加 mask
- 文字用绝对定位盖在外部容器上,不进被遮罩的盒子
- 别指望
z-index能绕过 mask —— 它发生在绘制阶段,跟层叠顺序无关
真正难调的永远不是写法,而是蒙版坐标系与目标元素尺寸、缩放、transform 的耦合关系;每次改 layout,几乎都要同步检查 mask-size 和渐变起止点是否还对得上。











