应使用:root和[data-theme="dark"]分别定义--img-brightness变量(如1和0.85),通过层叠优先级使filter: brightness(var(--img-brightness))自动响应主题切换;硬编码brightness(0.85)不生效是因为其值静态,无法随data-theme变化而更新。

直接结论:用 :root 和 [data-theme="dark"] 分别定义带单位的 CSS 变量,再在 filter 中通过 var(--brightness) 引用——不是靠 JS 切类名或硬写两套 filter,而是靠层叠优先级自动生效。
为什么 filter: brightness(0.85) 在暗黑模式下不生效?
不是代码没跑、也不是浏览器 bug,而是亮度值没“活”起来。硬编码的数值不会随主题切换自动更新;filter 属性本身不响应 DOM 属性变化,只认当前计算出的静态值。真正起效的是变量绑定 + 选择器优先级提升。
-
:root定义默认值(如--img-brightness: 1),亮色模式走这里 -
[data-theme="dark"]用更高特异性覆盖同一变量(如--img-brightness: 0.85) - 图片元素只需写一次
filter: brightness(var(--img-brightness));,无需 JS 干预切换 - 确保
data-theme是设置在或上,否则层叠链断裂
blur()、drop-shadow() 等带单位函数怎么设变量?
它们对单位极其敏感,变量值必须自带合法单位,不能靠 CSS 补、也不能靠 JS 拼。
-
--blur: 2px✅ 正确:blur(var(--blur))可用 -
--blur: 2❌ 失效:blur(2)不是合法长度值 -
--drop-shadow: "0 4px 8px rgba(0,0,0,0.2)"✅ 唯一例外:drop-shadow 接受字符串,必须加引号定义 -
--contrast: 1.1✅ 无单位函数可直接用小数,contrast(var(--contrast))合法
JS 动态更新多个滤镜变量时,为什么总丢值?
多个滑块同时拖动,频繁调用 element.style.setProperty() 会触发多次重排,中间状态被覆盖,最终只留下最后一次。
- 所有滑块的
input事件统一委托给一个requestAnimationFrame(updateVars) -
updateVars函数从dataset.value读当前值(如blurSlider.dataset.value),而非实时.value(可能未提交) - 集中调用
document.documentElement.style.setProperty(),顺序固定、无竞态 - 绝对不要操作
element.style.filter—— 这会清空你用 CSS 变量写的整条声明
Safari 15.4 之前不支持 filter: blur(var(--blur)) 怎么降级?
这不是兼容性 bug,是规范实现进度问题。Safari 15.4 之前遇到该写法会静默忽略整条 filter 声明,图片毫无反应。
- 用
@supports (filter: blur(1px)) and (filter: blur(var(--b)))检测是否支持变量用法 - 不支持时,回退到 JS 字符串拼接(
el.style.filter = `blur(${v}px)`)或纯 CSS 类切换 - 旧版 Safari 下,
drop-shadow(var(--s))也失效,需提前转义为完整字符串并内联 - 别依赖
will-change: filter强制硬件加速——旧版 iOS Safari 可能反而更卡
最难的从来不是写出那行 filter: brightness(var(--img-brightness)),而是判断哪张图该调、调多少:夜景图在暗黑模式下可能需要亮度=1甚至微提对比度,而 UI 截图则必须压到 0.85 左右才不刺眼。变量只是工具,取值才是经验。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











