css filter 的 brightness() 和 contrast() 可调图片亮度对比度,需用小数格式(如 brightness(0.8)、contrast(1.3)),顺序应为 brightness→contrast,父容器加 isolation: isolate 防截断,background-image 不支持 filter。

直接用 CSS 的 filter 属性就能设置图片的对比度和亮度,核心是 brightness() 和 contrast() 两个函数。关键不在“能不能”,而在“怎么写才真正生效”——很多失效问题其实源于数值格式、叠加顺序或父容器干扰。
数值必须写对:别用百分比,也别加单位
对比度必须写纯数字,比如 contrast(1.3),不能写 contrast(130%) —— Safari 和部分 Android WebView 会直接忽略甚至渲染成灰块。亮度则两种写法都行:brightness(0.8) 和 brightness(80%) 效果一致,但推荐统一用小数(更稳定,尤其在移动端 Safari 上,小数精度更可控)。
-
brightness(1)是原始亮度,不是“没效果”,它会覆盖上级样式 -
contrast(1)是原始对比度;contrast(0)是全灰,但旧版 Safari 渲染可能异常,建议用contrast(0.01)替代 - 别写
brightness(120)(漏%)或contrast(1.5px)(多单位),整条filter声明会被浏览器丢弃
顺序影响结果:先调亮度,再调对比度
filter 函数从左到右依次执行,顺序不同,视觉效果差异明显。例如:
-
filter: brightness(0.7) contrast(1.4):先压暗,再拉对比,暗部细节更容易保留 -
filter: contrast(1.4) brightness(0.7):先拉对比,再整体变暗,阴影容易变成死黑
推荐固定顺序:brightness → contrast → saturate → grayscale。调试时可逐个注释掉某个函数,比靠经验猜快得多。
父容器可能“吃掉”滤镜:加 isolation: isolate
如果给 <img> 加了 filter 却没反应,大概率是父元素触发了层叠上下文(比如设置了 opacity: 0.99、transform: translateZ(0) 或 will-change: transform),导致滤镜被截断。
- 最简解法:用一个
<div> 包住图片,并在该 <code><div> 上加 <code>isolation: isolate - 不需要改 HTML 结构逻辑,也不用动 JS,样式层面即可解决
- 注意:这个属性本身不触发新层叠上下文,只是确保子元素的 filter 能正常渲染
- 可行替代方案:用
<img>+position: absolute模拟背景图 - 或者接受限制,把调色逻辑移到真正的
<img>元素上 - Canvas 动态生成是另一条路,但成本高,适合需要精确像素控制的场景
背景图不支持 filter:别白费劲
filter 对 background-image 完全无效。写 div { background-image: url(x.jpg); filter: contrast(1.2); } 不会产生任何效果。











