不能直接给容器加filter: blur(),因其会模糊整个元素及其所有子元素(如文字、按钮),导致交互失效;正确做法是用position: absolute或fixed的::before伪元素承载背景并单独应用blur,实现分层模糊。

直接用 position 配合伪元素实现模糊蒙版,本质是“分层遮罩”,不是真蒙版——它靠视觉错位模拟 Photoshop 的效果,但必须手动控制层级、尺寸和背景同步,否则容易糊错地方或被裁掉。
为什么不能直接给容器加 filter: blur()
因为 filter: blur() 作用于整个元素及其子树,包括文字、按钮、输入框。比如给 .modal 加 filter: blur(8px),弹窗里的表单字段全糊了,用户根本没法操作。真正要模糊的只是它背后的页面内容,而不是它自己。
- 错误做法:
.modal { filter: blur(8px); }→ 整个弹窗变糊,交互失效 - 正确思路:用
::before伪元素单独渲染一层背景图,再对它模糊 - 关键前提:该伪元素必须脱离文档流(
position: fixed或absolute),且尺寸覆盖目标区域
::before 伪元素 + filter: blur() 的实操要点
这是最常用也最可控的方案,适用于静态区域(如弹窗背景、卡片浮层)。
- 伪元素必须显式设置
background-image,不能靠继承;否则模糊的是透明底色,看不出效果 -
background-size: cover和background-position: center必须写死,否则不同屏幕下背景偏移,模糊区域对不齐 - 如果父容器有
transform(比如scale(0.95))或overflow: hidden,::before可能被裁剪——此时得把伪元素提到html或body下,用fixed定位 - 移动端要注意:iOS Safari 在
blur(12px)以上可能降级为低精度模糊,甚至跳帧;建议模糊半径控制在2px–8px之间
如何让模糊区域精准对应内容位置?
靠 position: absolute + inset 或 top/left/right/bottom 手动对齐,不是自动跟随。
立即学习“前端免费学习笔记(深入)”;
- 若模糊区域是固定宽高的卡片:
.card::before { position: absolute; inset: 0; z-index: -1; } - 若需响应式适配(比如随视口滚动):用
position: fixed,配合calc()动态算坐标,例如top: calc(50vh - 100px); left: calc(50vw - 150px); - 绝对不能依赖
margin或padding来“推”伪元素位置——它不参与布局,推不动 - 检查是否被父级
overflow: hidden截断:打开 DevTools,看伪元素的盒子是否完整显示;若被裁,就换定位上下文
兼容性与 fallback 处理
IE 和旧版 Android WebView 不支持 filter,但你没法靠 CSS 自动降级——必须提前准备替代方案。
- 不要用
@supports (filter: blur())包裹整套逻辑,因为部分浏览器(如 Safari 14)支持语法但渲染异常 - 更稳妥的做法:JS 检测
CSS.supports('filter', 'blur(1px)'),失败时切换 class,改用预处理的模糊图或纯色半透背景 - SVG
<filter>方案虽兼容 IE10+,但无法动态调整半径,且需内联或外链 SVG,维护成本高,仅适合静态场景
真正难的不是写几行 CSS,而是让模糊层和真实背景像素严丝合缝对齐——哪怕 1px 偏移,都会在边缘露出清晰背景,破坏玻璃态效果。动手前先确认背景图加载完成、容器无 transform 干扰、伪元素未被 overflow 裁剪,这三步漏掉任何一步,效果就废一半。


















