Less中多个filter声明会互相覆盖,必须用Mixin拼接成单个字符串并用e()去除引号;backdrop-filter需手动添加-webkit-前缀且依赖透明背景与渲染上下文。

Less 本身不支持批量应用 filter,必须用 Mixin 封装单个组合字符串,否则多个 filter 声明会互相覆盖——这是最常被误以为“能叠加”的地方。
为什么多个 filter 声明会失效
浏览器只认最后一个 filter 声明,写两行就等于白写:
-
filter: blur(2px);→ 被下一行覆盖 -
filter: contrast(1.3);→ 最终生效的只有这行
Less 编译器不会合并它们,也不会报错。现象是:看起来“只生效了一个滤镜”,调试时查 computed style 会发现只有最后一项。
用 .filter() Mixin 动态拼接字符串
核心是把所有滤镜函数拼成一个空格分隔的字符串,再用 e() 去掉引号:
立即学习“前端免费学习笔记(深入)”;
- 每个参数对应一个滤镜函数,默认值设为“无效果”(如
@contrast: 1) - 用
& when ()条件判断是否需要拼入该滤镜,避免生成contrast(1)这种冗余项 -
e(@filter-list)必须加,否则编译出来是filter: "blur(2px) contrast(1.3)";(带引号=无效)
示例:
.filter(@blur: 0, @contrast: 1, @brightness: 1) {
@filter-list: ~"";
& when (@blur > 0) { @filter-list: ~"@{filter-list} blur(@{blur})"; }
& when (@contrast != 1) { @filter-list: ~"@{filter-list} contrast(@{contrast})"; }
& when (@brightness != 1) { @filter-list: ~"@{filter-list} brightness(@{brightness})"; }
filter: e(@filter-list);
}灰度切换要显式声明 transition
grayscale(0) 到 grayscale(1) 不会自动过渡,因为浏览器不认为函数调用可插值:
- 必须手动加
transition: filter 0.3s ease; - 参数统一用小数(
0.6)或百分比(75%),避免混用grayscale(100%)和grayscale(1) - 封装
.grayscale-toggle()时,用ispercentage()+@value * 0.01归一化,不然grayscale(75%)会被当成非法值
backdrop-filter 必须手写 -webkit- 前缀
Less 不处理前缀,backdrop-filter 在 Safari 和旧 Chrome 中缺 -webkit-backdrop-filter 就直接失效,且控制台不报错:
- 顺序必须是
-webkit-backdrop-filter在前,backdrop-filter在后 - 不能只包属性值,得用 Mixin 包裹整条规则块(含
background-color: rgba()和will-change: backdrop-filter) - 父容器若设了
overflow: hidden或纯色背景,毛玻璃会“看起来没效果”,这不是代码问题,是渲染限制
真正麻烦的不是怎么写,而是得同时管住三件事:字符串拼接逻辑、浏览器前缀硬编码、以及 backdrop-filter 依赖的透明背景和渲染上下文——漏掉任意一项,效果就断在生产环境里。


















