不能直接给body加filter: blur(),因为会模糊全部内容;需用::before伪元素分层实现背景模糊、前景清晰,配合position: fixed、100vw/vh尺寸、z-index: -1及独立背景设置。

全屏背景模糊为什么不能直接给 body 加 filter: blur()
直接对 body 或 html 应用 filter: blur(10px) 会让整个页面(包括文字、按钮、表单)一起模糊,失去可读性和交互性。这不是“背景模糊”,而是“整页糊掉”。真正需要的是:背景图模糊,前景内容清晰——这必须靠分层实现。
用 ::before 伪元素承载模糊背景的实操要点
核心思路是把模糊图层作为独立视觉层叠在底层,不干扰文档流中的内容。关键在于定位、尺寸控制和层级隔离:
-
position: fixed是必须的,否则伪元素会随内容滚动或受父容器约束,无法真正“全屏” -
top: 0; left: 0; width: 100vw; height: 100vh;确保覆盖视口,注意不是100%(百分比相对父容器,可能漏边) -
z-index: -1把它压到内容下方,但要小心:若父容器有overflow: hidden或transform,可能裁剪或隔离该伪元素 -
background-image必须设在伪元素上,不能依赖父元素继承;background-size: cover和background-position: center保证铺满且居中
示例代码:
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-image: url('bg.jpg');
background-size: cover;
background-position: center;
filter: blur(12px);
z-index: -1;
}
filter: blur() 的性能与兼容性陷阱
高斯模糊在 CSS 中开销不小,尤其在大分辨率或低功耗设备上容易掉帧。几个关键事实:
- 模糊半径超过
8px后,渲染耗时非线性增长,iOS Safari 在blur(15px)以上可能卡顿或降级为低精度模糊 - 部分安卓 WebView(如旧版 UC)完全不支持伪元素上的
filter,需加@supports (filter: blur(1px))条件包裹 - 不要对动态变化的背景(如视频、canvas 动画)用
filter,浏览器无法有效缓存,会持续重绘 - 若需响应式模糊强度,用媒体查询比 JS 操作
style.filter更稳定:@media (max-width: 768px) { body::before { filter: blur(6px); } }
为什么不用 backdrop-filter?它和这里说的不是一回事
backdrop-filter 是让元素“背后的内容”模糊(比如毛玻璃效果),但它要求背后有可穿透的区域(透明/半透),且只对**其自身的背景区域生效**。它不能用来模糊一个固定背景图——因为那张图是它自己的 background-image,不是“背后”的东西。想模糊一张静态图,只能走 filter + 分层路径。这点常被混淆。
真正容易被忽略的是:模糊图层如果用了 opacity 或带 alpha 的 background-color,会导致边缘发虚或叠加灰雾感。保持伪元素背景纯图片+无透明度,是最干净的起点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











