直接写 filter: grayscale(100%) 即可生效,值必须带 % 单位,范围 0%(原色)至 100%(全灰),ie 全版本不支持,父容器设置会影响内部所有图像及背景图,嵌套 filter 不叠加,组合时应按 blur→调色→去色顺序书写。

filter: grayscale() 怎么写才生效
直接写 filter: grayscale(100%) 就能立刻让图片变灰,不需要 JS 或额外包裹。但常见错误是漏括号或值:filter: grayscale、filter: grayscale(1)(虽然语法合法,但语义模糊,建议统一用百分比)、filter: grayscale(100)(缺%符号,Chrome 会忽略)。
值范围是 0%(原色)到 100%(全灰),中间值如 grayscale(70%) 是线性插值,适合做渐变过渡。IE 全版本不支持,别加 -ms-filter——它只支持极简的灰度开关,且已废弃。
- 必须写单位(%),不能省略
- 父容器设
filter: grayscale(100%),内部所有<img>、<svg></svg>中的<image></image>、甚至background-image都会一起变灰 - 若父级和子级都设了 grayscale,效果非叠加(比如 50% + 50% ≠ 100%),而是按渲染管线顺序复合,结果不可预测,尽量避免嵌套
filter: blur() 的单位和性能边界
blur() 必须带长度单位,blur(3) 是无效声明,DevTools 里会被划掉;正确写法只有 blur(3px)、blur(0.5em) 这类。移动端尤其要注意:超过 blur(20px) 后 GPU 渲染开销陡增,低端 Android 设备容易掉帧。
- 模糊半径建议控制在 0–10px 之间,背景虚化用
blur(6px)已足够柔和 - 和
transform: scale()同时使用时,模糊作用于缩放后的像素,可能放大失真 - 给
position: fixed元素加blur()容易出现边缘撕裂或滚动闪烁,这是合成层与视口滚动不同步导致的,临时缓解可加will-change: filter,但治标不治本
hover 时平滑切换灰度或取消模糊
只在 :hover 里写 filter: grayscale(0%) 或 filter: blur(0) 不会动,必须显式声明过渡行为。关键点是把 transition 写在默认状态里,且只针对 filter 属性——用 all 会导致无关属性也被过渡,性能差且不可控。
- 推荐写法:
img { filter: grayscale(100%); transition: filter 0.3s ease; }+img:hover { filter: grayscale(0%); } - 时间值选 0.2s–0.4s 最自然;太短像闪退,太长像加载中
- 如果同时改
opacity或transform,可以合并:transition: filter 0.3s, opacity 0.3s
多个 filter 函数组合时的顺序陷阱
filter 按从左到右顺序执行,不可逆。比如 grayscale(1) saturate(2) 先去色再拉饱和,实际无效;而 saturate(2) grayscale(1) 先拉饱和再变灰,结果仍是灰的,但中间计算路径不同,极端情况下会影响抗锯齿。
- 通用原则:先模糊(
blur),再调色(brightness、contrast等),最后去色(grayscale、sepia) -
blur(2px) brightness(80%) grayscale(100%)是安全组合;反过来写可能让模糊区域亮度异常 - 禁用按钮常用
filter: grayscale(100%) opacity(70%),但注意opacity是独立属性,不是 filter 函数,它影响整个元素(包括文字、边框),而filter只作用于像素内容
真正麻烦的是 fixed 元素加 filter 后的渲染撕裂,还有嵌套 filter 导致的非线性叠加——这两个问题调试起来没报错,但视觉上就是“不对劲”,得靠截图比对或录屏逐帧观察。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











