最简写法是filter: brightness(1.2) contrast(1.1),但需注意作用范围、重绘性能、父元素overflow裁切、inline元素需设display,且brightness/contrast参数支持数字或百分比,0为极值,连写顺序无关。

filter: brightness() 和 contrast() 怎么写才生效
直接加 filter: brightness(1.2) contrast(1.1) 是最简方式,但要注意:它只作用于元素自身及其后代,且会触发重绘(非合成层时可能卡顿)。如果目标是整页调光,得套在 body 或 html 上;若只想调某个图片或卡片,就挂到对应容器上。
常见错误是写了但没反应——大概率因为父元素有 overflow: hidden 且子元素用了 transform,导致 filter 被裁切;或者元素本身是 inline 元素(如 span),没设 display: inline-block 或 block,filter 不生效。
-
brightness()接受数字或百分比:brightness(1)、brightness(100%)是正常亮度;0全黑,2是两倍亮度 -
contrast()同理:contrast(1)或contrast(100%)是原始对比度;0灰成一片,2对比拉满(容易失真) - 两个函数可连写,顺序无关,浏览器自动合并为一个 filter 函数调用
动态改亮度/对比度时为什么卡、不平滑
用 JS 改 element.style.filter 每次都触发 layout → paint → composite,尤其在滚动中频繁修改,掉帧明显。真正该走的是 CSS 变量 + will-change: filter 配合硬件加速。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 先给元素加
will-change: filter(仅对需频繁变动的元素,别滥用) - 用 CSS 自定义属性传值,比如
style="--bri: 1.3; --con: 0.9;",然后 CSS 里写filter: brightness(var(--bri)) contrast(var(--con)); - 避免在
scroll事件里直接改 style,改用requestAnimationFrame节流 - 注意 Safari 对
filter的复合动画支持弱,多个 filter 函数同时过渡时可能跳变
兼容性坑:IE、旧版 Safari 和暗色模式冲突
filter 在 IE 完全不支持,Edge 16+ 才开始支持;iOS Safari 9.3+ 支持,但 iOS 12 之前对 filter 动画有渲染 bug(闪屏、残影)。更隐蔽的问题是:系统级暗色模式开启时,某些浏览器(如 Chrome 115+)会对 filter 值做隐式修正,导致你设的 brightness(0.8) 实际效果偏灰。
应对方式:
- 不用
@supports (filter: blur(1px))判断,改用@supports (filter: brightness(1))更准 - 对关键 UI,加降级:比如 fallback 到
opacity或 class 切换背景色 - 避免在
@media (prefers-color-scheme: dark)里再叠加filter,容易和系统调整叠加过载
和 backdrop-filter、SVG filter 混用时的优先级问题
如果同时用了 filter(作用于元素内容)和 backdrop-filter(作用于元素背后区域),它们互不干扰,但渲染层叠顺序会影响观感:比如一个半透明弹窗既设了 filter: brightness(0.9),又设了 backdrop-filter: blur(4px),那“变暗”只影响弹窗自身,模糊才影响背后内容。
容易被忽略的点:
-
backdrop-filter在 Firefox 默认关闭(需用户手动开layout.css.backdrop-filter.enabled),不能当主力方案 - SVG 的
<filter></filter>是另一套体系,和 CSSfilter名字一样但语法不同,混用会覆盖而非叠加 - 用
filter处理图片时,若图片本身带 alpha 通道(如 PNG 透明背景),contrast()可能意外强化边缘灰边
亮度和对比度看着简单,但一动起来,浏览器怎么算、在哪算、算几遍,全是细节。尤其是跨设备调同一组值,iOS 和 Android 渲染差异可能比参数差得还大。










