filter 仅对渲染盒生效,需避免 display: none、opacity: 0 或 overflow: hidden 裁剪;内联元素须设 display:block/inline-block;叠加用空格分隔;blur() 模糊整体,drop-shadow() 基于 Alpha 投影;backdrop-filter 才实现毛玻璃;Safari ≤12.1 不支持 drop-shadow();blur() 单位限 px/em/rem;hue-rotate() 必带 deg;SVG 滤镜仍是复杂效果主流方案。

filter 在 CSS 里怎么写才生效
直接写 filter 样式不会对所有元素起作用:它只对「渲染盒」有效,且要求元素不能是 display: none 或完全透明(opacity: 0 但未触发硬件加速时也可能失效)。最稳妥的做法是确保目标元素有明确的渲染层——加 transform: translateZ(0) 或 will-change: filter 能强制创建合成层,避免滤镜被静默忽略。
常见错误现象:filter: blur(2px) 写了但没模糊效果,检查是否父元素用了 overflow: hidden 且子元素模糊溢出被裁剪;或者元素本身是内联元素(如 <span>),需先设 display: inline-block 或 block。
-
filter必须写在要加效果的元素上,不能靠父级继承 - 多个滤镜函数叠加用空格分隔,不是逗号:
filter: brightness(1.2) contrast(0.9) saturate(1.5) - 动画
filter时,blur()和drop-shadow()性能开销大,频繁变化建议用will-change: filter提前提示浏览器
blur() 和 drop-shadow() 到底该选哪个
blur() 是高斯模糊,作用于整个元素及其内容(包括子元素、边框、背景),但会模糊掉所有细节;drop-shadow() 是基于 Alpha 通道的阴影滤镜,只对「有像素内容」的区域生成阴影,不模糊元素自身,更接近 box-shadow 但支持投影扩散和模糊半径,且能绕过元素形状(比如对带透明 PNG 的图标投阴影)。
使用场景举例:
立即学习“前端免费学习笔记(深入)”;
- 给文字加柔化边缘:用
blur(0.5px),但注意小值可能无感,blur(1px)起步较明显 - 给卡片加“浮起”感:优先用
drop-shadow(0 4px 8px rgba(0,0,0,0.15)),比box-shadow更自然,尤其对圆角或不规则图形 - 做毛玻璃效果:必须配
backdrop-filter: blur(10px),不是filter: blur()—— 后者模糊的是元素自己,前者模糊的是背后内容
浏览器兼容性最常踩的坑
filter 在 Chrome/Firefox/Safari(最新版)基本没问题,但老版本 Safari(≤12.1)不支持 drop-shadow(),IE 完全不支持 filter(除了已废弃的 IE 滤镜语法)。更隐蔽的问题是:Safari 对 filter 动画的支持不稳定,尤其是 blur() 值为 0 时动画跳变,建议用 filter: url(#svg-filter) 或 JS 控制过渡帧来规避。
参数差异要注意:
-
blur()单位只能是px、em、rem,不能用%或无单位数字 -
hue-rotate()参数是角度,必须带deg(如hue-rotate(90deg)),写成90会被忽略 -
contrast()和brightness()接受无单位数值,1表示原始值,0表示全黑(contrast=0 就是纯灰)
自定义滤镜只能靠 SVG?其实还有 CSS Houdini
标准 CSS filter 函数有限,真要实现复杂效果(比如故障风 glitch、动态噪点、色键抠像),SVG 滤镜仍是目前最通用方案:用 <filter> + <feConvolveMatrix> 等定义,再通过 filter: url(#my-filter) 引用。但注意 SVG 滤镜路径必须同源,跨域资源无法引用。
CSS Houdini 的 Paint API 和 Worklets 理论上可扩展滤镜,但截至 2024 年,仅 Chromium 系部分支持,且需开启实验标志,生产环境不可靠。所以实际项目中,别指望用 registerProperty 或 paint() 替代 SVG 滤镜。
容易被忽略的一点:backdrop-filter 和 filter 都会触发新的层叠上下文(stacking context),可能意外改变 z-index 层级关系,调试时发现元素被盖住,先查是不是加了这两个属性之一。



















