必须将所有图层写入单个background声明,用逗号分隔,并严格匹配background-blend-mode值数量与顺序;底色须用linear-gradient替代background-color,各层size/position/repeat须显式指定。

background 声明必须单行写,不能拆成多个属性
很多人封装多重背景时,把 background-image、background-position、background-size 和 background-blend-mode 分开写,结果图层不混合、纹理不生效。这是因为 background-blend-mode 只对同一 background 属性内逗号分隔的图层起作用;一旦拆开,background-color 或单独写的 background-image 就成了独立层级,不参与混合计算。
正确做法是:所有图层(图片、渐变、模拟色块)都塞进一个 background 值里,用逗号分隔,并严格对齐顺序与 background-blend-mode 的值数量。
图层数量、顺序和 blend-mode 必须一一对应
background-blend-mode 的值个数必须等于图层数,且顺序从左到右——第一个值控制最上层图层与第二层的混合,第二个值控制第二层与第三层的混合,以此类推。常见错误是漏写或写多一个值,导致整条声明被浏览器忽略。
- 三层图层(纹理图 + 遮罩渐变 + 底色渐变)→ 必须写三个
background-blend-mode值,如multiply, normal, normal - 底色不能用
background-color,得用linear-gradient(#f5f5f5, #f5f5f5)替代,否则它不被视为“图层” - 纹理图推荐 PNG-24 + Alpha 通道,避免 JPG 色彩空间干扰混合效果
@mixin 封装时必须显式传入每层的 size/position/repeat
直接封装一个“带纹理的背景”宏,却不接收 background-size 和 background-position 参数,上线后大概率出问题:默认 auto 会让小尺寸纹理图按原始像素铺满整个容器,看起来像一张大贴图而非细腻叠加。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 每个图层的
background-size、background-position、background-repeat都要作为参数传入 mixin - 纹理图常用
100px 100px+repeat,遮罩层用cover+no-repeat,底色层同理 - 示例调用:
@include textured-bg(url("noise.png"), 100px 100px, right bottom, repeat, linear-gradient(rgba(0,0,0,0.1), rgba(0,0,0,0.1)), cover, center, no-repeat);
SCSS 中用 unquote(join()) 处理多层 background 字符串
SCSS 编译时若直接 @return $list 返回图层字符串数组,最终 CSS 会变成带双引号的字符串,比如 "url(a.png), url(b.png)",浏览器直接忽略整条 background 声明。
必须用两步处理:
- 先用
join(", ", $layers)拼接各图层声明 - 再套一层
unquote()去掉最外层引号,生成纯 CSS 字面量 - 别在 mixin 里用
rgba()或darken()直接拼颜色值——它们提前求值后会被当作文本字面量,失去动态性
最容易被忽略的是:图层顺序决定了视觉叠放关系,而 background-position 的坐标系原点始终是容器左上角,不是上一层图层——这点在做偏移定位时经常导致错位。


















