使用 css 设置 blur 设置背景模糊的时候,使用了 transform: scale(10px); ,在移动端真机上测试时,无论安卓还是 iOS,都会出现页面首次加载,图片会首次请求的时候,先出现黑色蒙层遮罩,再渲染图片,黑色蒙层遮罩消失的情况,这在一些已实现的按钮下面还会出现按钮下方的周边区域却无黑色遮罩的情况。
将 transfrom: scale 改成 transfrom: scale3d
代码实现:
以下为 less 实现的一个混合函数,可以直接使用
/* 完整的背景高斯模糊样式 - 包含模糊层和原图层 */
/* @scale: 模糊图片放大倍数, @blur: 模糊像素, @blurImgUrl: 模糊层图片地址, @bgImgUrl: 背景层图片地址(可选) */
/* 注意:调用者需要自行设置定位方式(relative/absolute/fixed) */
.bg-blur(@scale: 1.5, @blur: 10px, @blurImgUrl: '', @bgImgUrl: '') {
overflow: hidden;
position: relative;
// 模糊层(底层)- 独立控制,只要传入了模糊图片就显示
& when not (@blurImgUrl = '') {
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: @blurImgUrl;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
-webkit-filter: blur(@blur);
filter: blur(@blur);
-webkit-transform: scale3d(@scale, @scale, 1);
transform: scale3d(@scale, @scale, 1); /* 触发 GPU 加速,关键步骤,使用 transform:scale 会导致真机页面初次展示有黑色遮罩出现的问题 */
will-change: transform; /* 提示浏览器优化 */
z-index: 1;
}
}
// 原图层(顶层)- 独立控制,只要传入了背景图片就显示
& when not (@bgImgUrl = '') {
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: @bgImgUrl;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
z-index: 2;
}
}
}filter: blur() 的渲染冲突scale()) 的渲染流程scale())和 CSS 滤镜(如 blur())通常由 CPU 处理,而非 GPU。::before)同时应用 filter: blur() 和 scale(1.5) 时,浏览器会分两步渲染:blur(),此时透明像素会被视为黑色,导致黑色蒙层。scale3D()) 的渲染优化scale3D() 会触发浏览器的硬件加速(通过创建新的 合成层),将变换和滤镜的计算交给 GPU 处理。filter: blur() 是“帮凶”?blur() 滤镜在作用于透明像素时,会将其视为黑色(这是 CSS 规范的行为)。如果图片未加载完成或伪元素背景透明,就会先显示黑色。scale() 会阻塞后续渲染步骤,导致黑色蒙层短暂停留;而 scale3D() 通过 GPU 加速跳过此阻塞。filter: blur()(无缩放).element::before {
filter: blur(10px);
background-color: transparent; /* 透明背景 */
}scale(1.5)(无模糊).element::before {
transform: scale(1.5);
background-color: transparent;
}filter: blur() + scale3D(1.5, 1.5, 1).element::before {
filter: blur(10px);
transform: scale3D(1.5, 1.5, 1);
}总结:
filter: blur() + 透明背景 共同导致的渲染中间状态。filter 和 transform 时,优先选择 scale3D,并配合 will-change 或占位策略。通过这种方式,你可以彻底避免黑色闪现,同时保持模糊背景的平滑渲染效果。