mask-image 必须搭配 mask-size、mask-repeat、-webkit-mask-image 才生效,因默认依赖 alpha 通道且 WebKit 需前缀,单独声明会被忽略。

mask-image 能实现比 clip-path 更自然的异形裁剪,但直接写 mask-image 会完全失效——它必须搭配至少三个配套声明才起作用。
为什么写了 mask-image 却没效果
常见错误是只加一行 mask-image: url(mask.png),浏览器直接忽略。因为 mask-image 默认行为依赖 alpha 通道,而它的生效前提被隐式绑定在几个关键属性上:
-
mask-mode必须为luminance或alpha(现代浏览器默认alpha,但旧 Safari 可能不认) -
mask-size若未设,默认按原始尺寸渲染,遮罩图太小就只盖住左上角一小块 -
mask-repeat默认是repeat,一张小遮罩图会平铺,造成奇怪的网格状裁剪 - 所有 WebKit 浏览器(Chrome、Safari、Edge)必须同时写
-webkit-mask-image,否则白写
用 PNG 遮罩图裁剪图片的最小可行配置
假设你有一张 logo.jpg 和一张带透明通道的 frame.png(非 JPG!JPG 没 alpha),要让图片严格按遮罩形状显示:
.cover {
width: 200px;
height: 200px;
background: url(logo.jpg);
background-size: cover;
-webkit-mask-image: url(frame.png);
mask-image: url(frame.png);
-webkit-mask-size: 100% 100%;
mask-size: 100% 100%;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
}
注意:mask-size 值必须显式写成 100% 100%,不能简写为 100%(后者会被解析为 100% auto,高度失真)。
立即学习“前端免费学习笔记(深入)”;
用 CSS 渐变替代图片做动态遮罩
不需要切图也能做软边或过渡裁剪,比如实现「聚光灯」鼠标跟随效果:
- 渐变值本身可作为
mask-image,例如mask-image: radial-gradient(circle at var(--x) var(--y), black, transparent 60%) - 必须配合
mask-mode: alpha(尤其在 Firefox 中,否则渐变不触发透明度计算) - 变量
--x/--y需通过 JS 实时更新,CSS 自身无法读取鼠标坐标 - 这种写法在 Safari 16.4+ 才稳定支持
mask-mode,更早版本需 fallback 到clip-path硬边方案
和 clip-path 混用时谁控制最终形状
两者叠加时顺序固定:clip-path 先执行,硬裁出轮廓;mask-image 后执行,在该轮廓内再按透明度做二次软处理。例如:
-
clip-path: polygon(0 0, 100% 0, 100% 100%)先切掉右下角三角形 - 再叠一层
mask-image: url(fade-edge.png),会让剩余区域边缘带羽化 - 反过来写(
mask-image在前)也没用,浏览器强制按此顺序合成
真正容易被忽略的是:mask-image 的透明度计算基于原始元素内容,不是 clip-path 裁剪后的结果——也就是说,遮罩图的坐标系始终以整个元素左上角为原点,不随 clip-path 移动或缩放。


















