Less中mask属性需手动双写-webkit-mask-image与mask-image且顺序固定,路径必须一致;不支持变量拼接url;SVG内联需转义并设xmlns和utf8;mask-mode与mask-composite影响合成逻辑。

Less里直接写mask属性和CSS原生写法没区别
Less只是CSS预处理器,编译后还是输出标准CSS,所以mask相关的语法、值、单位、浏览器前缀规则,完全遵循CSS规范。别指望Less能帮你自动补-webkit-mask或推导mask-image路径——它不处理运行时逻辑,也不做特性检测。
实际用的时候,得自己判断目标环境是否支持mask(比如Safari 15.4+才支持mask-border,Chrome从110起支持mask-composite),然后手动加前缀或用PostCSS补全。Less本身不参与这个过程。
- 所有
mask子属性都必须显式写出:mask-image、mask-size、mask-position等 - URL路径要相对编译后的CSS位置,不是Less源文件位置(容易错配)
- 不能用Less变量直接拼接
mask-image: url(@svgPath)再带参数,因为url()是CSS函数,不是Less函数,变量插进去会被当字面量解析
用mask-image配合SVG实现非矩形裁剪
最可控的方式是用内联SVG作为遮罩源。Less里可以定义变量存SVG内容,但必须转义成单行字符串,并用%编码特殊字符(比如#要写成%23),否则编译会报错或被截断。
@mask-triangle: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpolygon points='0,0 100,0 50,100' fill='%23fff'/%3E%3C/svg%3E\")";
然后在样式中引用:
立即学习“前端免费学习笔记(深入)”;
.hero {
-webkit-mask-image: @mask-triangle;
mask-image: @mask-triangle;
}
- 注意
fill必须是纯白(#fff或white)才能透出内容;黑或透明区域会裁掉 - SVG的
viewBox尺寸影响缩放行为,和mask-size配合使用时容易错位 - 不要在SVG里用
<defs></defs>或外部<use></use>,内联数据URI不支持跨引用
mask-mode和mask-composite决定叠加逻辑
多个遮罩层叠时,mask-mode控制每个遮罩是“亮度模式”还是“alpha模式”,而mask-composite决定它们怎么合成(类似Photoshop的图层混合)。这两个属性目前只有较新浏览器支持,且默认值容易误导:
-
mask-mode: luminance(默认):按灰度值解释遮罩,纯白=100%显示,纯黑=0%显示 -
mask-mode: alpha:只看遮罩自身的alpha通道,忽略颜色 -
mask-composite: add(默认):多个遮罩取并集;换成intersect才是交集(更常用) - 如果同时设了
mask-image和mask-border,mask-composite才真正生效
Less里写就是直来直去:
.card {
mask-image: url(mask1.svg), url(mask2.svg);
mask-composite: intersect;
mask-mode: alpha, alpha;
}
动态切换遮罩时避免重排重绘
用Less变量或mixin生成多套mask规则没问题,但运行时靠JS切换class触发遮罩变化,要注意性能。Chrome里mask-image变更会触发布局重算,尤其当遮罩含模糊滤镜(mask-image: url(blur.svg))时更明显。
- 优先用
mask-position位移做“滑动遮罩”动画,比切换整个mask-image便宜得多 - 避免在
:hover里突然加载大尺寸SVG遮罩,先预加载到CSS background-image里备用 - 移动端Safari对
mask动画支持弱,mask-size缩放常卡顿,改用transform: scale()包裹容器更稳
复杂图形裁剪真正难的不是写法,而是遮罩资源的尺寸控制、多层合成时的模式匹配,以及不同引擎对mask-border和mask-clip的实现差异——这些没法靠Less抽象掉。


















