CSS如何实现复杂背景纹理叠加:利用SCSS混合宏简化层叠 background-blend-mode 必须写在单个 background 声明里 你是不是也遇到过这种情况:明明设置了background-image和background-color,再配上background-blend-mode

你是不是也遇到过这种情况:明明设置了background-image和background-color,再配上background-blend-mode,结果纹理和底色却“各自为政”,完全没有混合效果?问题就出在写法上。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
关键在于,background-blend-mode这个属性,它只认同一个background属性值里用逗号分隔开的那些“图层”。如果你把background-color单独拎出来写,那它就成了一个独立的背景层,压根不会参与到background-blend-mode的计算中去。
所以,正确的姿势是什么?得把所有东西——纹理图、渐变遮罩、模拟的底色——统统打包塞进一个background声明里。记住,后写的图层会盖在上面:
div {
background:
url("noise.png"), /* 纹理图,放最上层 */
linear-gradient(rgba(0,0,0,0.1), rgba(0,0,0,0.1)), /* 半透明遮罩 */
#f5f5f5; /* 底色,必须用渐变模拟而非 background-color */
background-blend-mode: multiply, normal, normal;
background-repeat: repeat, no-repeat, no-repeat;
background-size: 100px 100px, cover, cover;
}
background-color,得用linear-gradient(#f5f5f5, #f5f5f5)这样的渐变来模拟,这样才能被识别为一个可混合的图层。background-blend-mode值的数量必须和图层数严格对应,顺序也不能乱。为了复用,我们常会封装一个“纹理背景”的SCSS混合宏。但这里有个大坑:如果封装时没控制好background-size和background-position,上线后纹理很可能被拉伸、错位,甚至完全看不见。因为默认的background-size: auto会让纹理图以其原始尺寸铺满容器,而大多数纹理图的设计初衷是小尺寸重复平铺。
怎么办?经验表明,最稳妥的做法是使用带参数的@mixin,把关键行为都约束好:
立即学习“前端免费学习笔记(深入)”;
@mixin textured-bg(
$texture: url("noise.png"),
$base-color: #fff,
$texture-size: 64px 64px,
$texture-pos: 0 0,
$blend-mode: multiply
) {
background:
$texture,
linear-gradient($base-color, $base-color);
background-blend-mode: $blend-mode, normal;
background-repeat: repeat, no-repeat;
background-size: $texture-size, cover;
background-position: $texture-pos, center;
}
$texture-size这类参数必须显式传入,例如@include textured-bg($texture-size: 32px 32px),不能依赖默认值。$texture-size)设置默认值或!default很容易掩盖问题,不同纹理图的物理尺寸差异很大,人工指定更可靠。@if去自动推断尺寸,这往往会导致意想不到的渲染结果。想让文字“透”出背后的纹理,营造融合感?这里要分清两兄弟:mix-blend-mode和background-blend-mode。可千万别在同一个元素上同时启用它们。
mix-blend-mode会让整个元素(包括它的文字、边框、阴影)去和它背后的DOM层进行混合。而background-blend-mode只负责混合自己background属性里的那几个图层。两者混用,效果会互相干扰,纹理可能就“变味”了。
来看一个典型的错误示范:
.card {
background: url("paper.png"), #eee;
background-blend-mode: overlay;
mix-blend-mode: multiply; /* 这会让 card 文字也去和父容器混合,纹理变味 */
}
mix-blend-mode,并且确保背景只是单一的background-image,别叠其他图层。background-blend-mode,同时关掉mix-blend-mode。mix-blend-mode放在外层容器,background-blend-mode放在内层元素上,把它们隔离开。使用SCSS混合宏时,得留意编译后的CSS体积。每次@include,都会把整个mixin的样式复制一遍。如果一个三层背景的mixin被调用了10次,CSS就会膨胀10倍。特别是当每次调用还传入不同的$texture-size或$blend-mode时,浏览器很难合并这些重复的规则。
%placeholder选择器配合@extend来替代@mixin。@extend会在编译时合并相同规则,只生成一次CSS。$tex-noise: url("noise.png"),避免在多个mixin参数里反复书写相同的字符串。/* scss-lint:disable */这类注释临时关闭样式检查,但上线前务必清理干净。要知道,CSS压缩工具对重复的background声明优化能力有限。最后提一个最隐蔽的坑:如果纹理图本身带有Alpha渐变,叠加后可能会导致边缘发虚。这种问题不会抛出任何错误,只能靠人眼仔细比对单独打开的纹理图和最终的页面渲染效果。多检查一步,总是没错的。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述