直接用filter加滤镜需注意:blur()等必须带单位,多函数用空格分隔且顺序影响结果;overflow:hidden会裁剪溢出效果;img上直接:hover不兼容移动端,应包裹容器并设overflow:hidden和transform:translatez(0)。

直接用 filter CSS 属性就能加滤镜,但写错顺序、漏单位、被父容器裁掉、或在 <img> 上直接写 :hover,都会让效果“看似没生效”。
filter 值怎么写才不丢效果
不是所有写法都安全,尤其组合多个函数时:
-
blur()必须带单位,如blur(1.2px),写成blur(1.2)无效 -
hue-rotate()和drop-shadow()必须带单位,hue-rotate(45deg)、drop-shadow(0 0 8px rgba(0,0,0,0.2)) -
brightness()、contrast()、saturate()用小数更稳,如brightness(0.9)、contrast(1.15),避免百分比解析歧义 - 多个函数用空格分隔,顺序影响结果:
grayscale(1) contrast(0.8)和contrast(0.8) grayscale(1)渲染不同 -
drop-shadow()不是图像滤镜,它作用于整个元素的最终输出框,应放在 filter 链末尾
为什么加了 filter 却看不见 blur 或阴影
大概率不是代码问题,而是渲染被截断或层叠上下文干扰:
- 父容器设了
overflow: hidden——blur(1px)或drop-shadow()溢出的像素会被直接裁掉,哪怕只多 1px - 图片外层用了
transform: scale(1)或will-change: transform,会创建新层叠上下文,导致filter只作用于子内容,而非视觉整体 - IE(含 IE11)完全不支持
filter,需用@supports (filter: blur(1px))包裹降级逻辑 - 图片跨域但未配 CORS,
filter显示正常,但后续若用canvas读取会报SecurityError,容易误判为滤镜失效
hover 滤镜动画卡顿或边缘模糊怎么办
直接在 <img> 上写 :hover 是高危操作,尤其在移动端和 Retina 屏:
-
<img>是替换元素,Safari iOS 和旧版 Chrome Android 对其:hover支持极弱,必须用容器包裹(如<div class="img-wrap">) <li>容器要设 <code>overflow: hidden防溢出,图片本身加transform: translateZ(0)或will-change: filter(仅在:hover里写)强制走 GPU 合成层 - 别同时动画
blur()和hue-rotate()—— 两者都是像素重采样密集型,极易掉帧;可用transform: scale(1.003)替代部分动态需求 - 打开 Chrome DevTools → Rendering → 勾选 “Paint flashing”,如果 hover 时大片绿色持续闪,说明正在软件渲染回退,GPU 没接管
- 想控制高光/阴影分离、青橙对比、胶片颗粒?必须用
canvas+getImageData()手动遍历像素,filter的线性变换做不到 - 处理大图(>1000×1000)时主线程卡顿?优先用
OffscreenCanvas移入 Web Worker,或用requestIdleCallback分块处理 - 要实时视频滤镜或复杂算法(如油画、浮雕)?得上 WebGL + GLSL 着色器,但开发成本陡增,别为单张静态图引入整套管线
- 注意:所有 canvas 方案都绕不开跨域检查,
img.crossOrigin = 'anonymous'必须在src赋值前设置
需要自定义效果(比如复古/虚幻/噪点)时该选什么方案
CSS filter 到此为止,再往下必须换技术栈:
真正难的从来不是“怎么加滤镜”,而是判断哪一层该由 CSS 扛、哪一层必须进像素阵列——多数翻车,都发生在没看清这个边界就开干。











