先记住这个答案
filter 作用在元素自身上,写 filter: blur(10px) 整个元素连文字一起变模糊。backdrop-filter 作用在元素背后那层画面上,元素自身的文字和内容完全不受影响,透过半透明背景看到的背后内容才是模糊的。iOS 系统的通知中心、macOS 的侧边栏那种毛玻璃效果,用的就是 backdrop-filter: blur()。
filter模糊自身,背景滤镜模糊背后- 元素背景必须半透明才能看到效果
- 会创建新的层叠上下文和合成层
- 移动端大面积使用会影响帧率
毛玻璃效果的标准写法
做毛玻璃效果的关键不只是加 backdrop-filter,还要让元素自身的背景半透明,否则模糊效果会被不透明的背景完全遮住,等于白加。
.navbar {
position: fixed;
top: 0;
width: 100%;
/* 背景必须半透明,才能透出模糊效果 */
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px); /* Safari 需要前缀 */
}这里 rgba(255, 255, 255, 0.6) 的透明度 0.6 是关键。设成 1 就完全不透明,看不到任何模糊;设成 0 又太透了,模糊效果不明显。通常 0.5 到 0.8 之间的值最自然。
Safari 目前仍然需要 -webkit-backdrop-filter 前缀。Chrome、Edge、Firefox 都已经支持无前缀写法。
filter 和 backdrop-filter 一起用会怎样
两个属性可以同时写在一个元素上,效果叠加但互不干扰。filter 处理的是元素自身的渲染结果,backdrop-filter 处理的是元素下方的画面,两者在不同的层上分别计算。
比如给一个浮层同时加 backdrop-filter: blur(10px) 和 filter: drop-shadow(0 4px 6px rgba(0,0,0,0.3)),背后的内容被模糊,浮层自身带投影,两个效果都生效。
但要注意,一旦给父元素加了 filter,它就会成为子元素 position: fixed 的包含块,子元素的固定定位会失效。这个副作用 backdrop-filter 没有。
不支持时怎么降级
可以用 @supports 检测。不支持 backdrop-filter 的旧浏览器可以退化成纯色半透明背景,体验差一点但不影响使用。
.overlay {
/* 默认降级:纯色半透明 */
background: rgba(255, 255, 255, 0.85);
}
@supports (backdrop-filter: blur(1px)) {
.overlay {
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
}
}降级方案里把透明度调高一点(0.85),虽然没有模糊效果,但文字依然可读。支持 backdrop-filter 时再把透明度调低(0.5),让模糊效果更明显。
容易答错的地方
- 忘了设半透明背景
- 写了
backdrop-filter: blur(10px)但背景是background: white,模糊效果完全被遮住,看起来像没加一样。检查的时候临时把背景改成transparent,如果模糊出现了,就是透明度的问题。 - 把模糊半径设得过大
blur(50px)以上在移动端会明显掉帧,因为每一帧都要对背后区域做高斯模糊。实际项目里 8px 到 20px 就足够了。如果面积还很大,可以考虑用will-change: backdrop-filter提前提升合成层,但也要在动画结束后移除。- 以为
backdrop-filter能穿透多层 backdrop-filter只处理当前元素正下方一层的内容。如果中间还隔了一个不透明的元素,那层内容被遮住了,backdrop-filter也模糊不到更下面的内容。
面试官还会怎么问?
filter: blur() 和 backdrop-filter: blur() 的性能差距大吗?
filter: blur() 只需要对元素自身的位图做一次模糊,开销固定。backdrop-filter: blur() 每帧都要把元素下方的内容截取出来做模糊,如果背后的内容频繁变化(比如视频、动画),开销会大得多。面积越大、模糊半径越大,性能差距越明显。
backdrop-filter 除了 blur 还能用什么滤镜函数?
和 filter 一样,backdrop-filter 支持所有 CSS 滤镜函数:brightness()、contrast()、grayscale()、saturate()、hue-rotate()、invert()、sepia()、drop-shadow() 等,也可以用空格分隔同时叠加多个。
为什么 filter 会影响子元素的 position: fixed?
filter 会让元素创建一个新的包含块。根据规范,position: fixed 的包含块本来是视口,但如果祖先元素有 filter(值不是 none),fixed 就会相对于这个祖先定位。backdrop-filter 不会产生这个影响。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。