不能直接给body加filter: blur(),因为会模糊全部内容;应使用伪元素承载背景图并单独模糊,注意单位必须正确、避免裁剪、禁用高频js修改及合理组合滤镜。

filter: blur() 为什么不能直接给 body 加?
直接写 body { filter: blur(8px); } 会让整个页面文字、按钮、输入框全糊掉——这不是背景模糊,是废操作。blur 作用于元素及其全部子内容,包括你不想模糊的交互控件。
真正要模糊的只是「背景图」那一层,其他内容必须保持清晰。所以必须分层:用伪元素承载背景图,再单独对其加 filter: blur(),主内容层完全不参与模糊计算。
- 伪元素必须设
z-index: -1或position: fixed确保在内容之下 - 背景图必须显式写在伪元素上,不能靠继承;
background-size: cover和background-position: center都得手动声明,否则可能拉伸或偏移 - 父容器若有
transform或overflow: hidden,伪元素会被裁剪,此时得把伪元素提到html上,或改用绝对定位容器
blur() 参数写错就等于没写
blur() 只接受带单位的长度值,blur(5)、blur(5%)、blur(0.5rem)(除非 root font-size 刚好是 10px)全都会被浏览器忽略——DevTools 里样式还在,但实际无效。
常见错误现象:写了样式却没模糊效果,检查 computed 样式发现 filter 值是 none,大概率就是单位错了。
- 推荐用
px,兼容性最稳;rem可以,但需确认设计稿基准 - 首屏加载时给未就绪的
<img>提前加filter: blur(4px),会闪一下才模糊——因为 filter 作用于渲染后的像素,资源没加载完就没像素可处理 - 移动端尤其敏感:iOS Safari 在
blur(12px)以上可能降级为低精度模糊;安卓部分旧 WebView(如 UC)压根不支持伪元素上的filter
动画中频繁改 style.filter 就是卡顿源头
用 JS 每帧执行 element.style.filter = 'blur(' + i + 'px)',会强制重绘整层,尤其在滚动或 hover 动画里,极易掉帧。
高性能做法是只用 CSS transition 或 animation 控制模糊变化,让浏览器自行调度 GPU 合成:
- 给元素加
transition: filter 0.3s ease,然后仅切换 class 触发变化 - 避免在
requestAnimationFrame里反复写内联style.filter - 如果必须 JS 控制,用
will-change: filter提前提示合成层,但别滥用,它本身有内存开销
多个滤镜组合时顺序决定最终效果
filter 函数从左到右执行,顺序不同结果差异明显。比如 blur(2px) brightness(1.2) 是先模糊再提亮;反过来则可能放大噪点、让边缘更刺眼。
典型场景:想让模糊背景更柔和,不是一味加大 blur() 值,而是配合 contrast(0.9) 或 opacity(0.95) 降低锐度感。
- 调试时建议单个滤镜逐个加,观察叠加影响
-
drop-shadow()和blur()混用容易出现双影,慎用 - 所有滤镜都在同一渲染层处理,复杂链式调用(超 5 个)可能触发软件渲染回退,性能下降明显
真正难的不是写对一行 filter: blur(6px),而是确保它只作用在该作用的图层、单位没错、不被父容器裁剪、也不在动画里被高频重写——这些细节漏掉一个,效果就打折扣,甚至白忙活。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











