contrast()必须用小数(如contrast(1.5)),禁用百分比;父容器触发层叠上下文时filter失效,需加isolation: isolate修复;filter不作用于background-image。

直接用 filter: contrast(),但必须写小数,不能写百分比;父容器有层叠上下文时,filter 会失效——加 isolation: isolate 就行。
contrast() 参数只能是纯数字,不是百分比
写 contrast(150%) 看起来合理,但 Safari、旧版 Android WebView 会直接忽略或渲染成灰块。规范要求传入无量纲数值:contrast(1.5) 表示原始对比度的 1.5 倍,contrast(1) 是原始状态,contrast(0.01) 比 contrast(0) 更稳妥(后者在某些 Safari 版本里可能崩溃或全灰)。
常见错误现象:
- Chrome 里正常,Safari 里图片变灰或没变化
- 调试器里看到
filter属性已生效,但视觉无反应
父元素触发层叠上下文时,filter 被截断
只要父容器设置了 opacity: 0.99、transform: translateZ(0)、will-change: transform 或 contain: paint,就会创建新的层叠上下文,导致子元素的 filter 不再作用于最终合成层。
解决方法很简单:
- 给
<img>包一层<div> <li>在该 <code><div> 上加 <code>isolation: isolate - 把
filter: contrast(1.3)移到这个<div> 上 <p>不需要改 JS,也不用动图片本身,更不用加额外类名到 <code><img>标签。和
brightness()一起用,顺序决定效果filter: brightness(0.8) contrast(1.4)和filter: contrast(1.4) brightness(0.8)渲染结果不同:- 先
brightness再contrast:暗部保留更多细节,适合压暗后拉对比 - 先
contrast再brightness:容易让阴影区域直接死黑
推荐固定顺序:
brightness → contrast → saturate → grayscale。调试时逐个注释掉某个函数,比靠猜快得多。filter对background-image完全无效你写
div { background-image: url(x.jpg); filter: contrast(1.2); },不会有任何效果。CSS 的filter只对作为独立渲染对象的元素生效(比如<img>、<svg></svg>、<canvas></canvas>),不穿透到背景图。如果必须调背景图对比度,只有三个现实选项:
- 换用
<img>+position: absolute模拟背景图 - 用 Canvas 动态加载并处理图片后再绘制
- 接受它不支持的事实,改用服务端预处理 WebP/JPEG
最常被忽略的一点:很多人反复检查
filter语法、浏览器兼容性,却忘了查父容器是否悄悄触发了层叠上下文——那个opacity: 0.99往往藏在全局 CSS 或第三方组件里,肉眼根本看不见。 - 先











