必须将CSS变量定义在:root并用document.documentElement.style.setProperty()修改,否则因作用域限制或缺少fallback而静默失效;变量名须以--开头、大小写敏感、值需为合法CSS字符串。
直接改 document.documentElement.style.setProperty() 就行,但必须写对目标元素、变量名和值格式,否则静默失效。
setProperty 写在按钮上没用?因为伪元素(如 ::before)读取变量时,会沿 DOM 树向上继承 —— 它只认最近的、声明了该变量的祖先。如果你把 --icon-color 写在 .btn 元素的 style 上,那只有这个按钮及其后代能读到;而 ::after 是它的子级,能读到,但其他组件就完全看不到。
真正要全局生效,变量必须定义在 :root,JS 修改也得统一写到 document.documentElement(即 <html> 元素):
document.documentElement.style.setProperty('--theme-bg', '#1a1a1a') ✅ 全局可读btn.style.setProperty('--theme-bg', '#1a1a1a') ❌ 仅限 btn 及其子元素document.body.style.setProperty('--theme-bg', '#1a1a1a') ⚠️ 不推荐:body 不是根,继承链可能中断setProperty 的变量名和值有哪些硬性要求?拼错一个字符就白写。常见失效点全在这儿:
立即学习“前端免费学习笔记(深入)”;
-- 开头,setProperty('theme-bg', ...) 是错的,得写 '--theme-bg'
setProperty('--size', 16) 会失败,得写 '16px' 或 '1rem'
--BgColor 和 --bgcolor 是两个变量getPropertyValue('--theme-bg') 返回值带首尾空格,要用 .trim()
不是 JS 没执行,而是 CSS 层面卡住了:
var(--color) 却没写 fallback:color: var(--color) → 如果 --color 未定义或为空,浏览器直接回退到 inherit,看起来“没变”。应写成 color: var(--color, #333)
:root 外定义,比如写在某个 .card 类里,那它只在该类作用域内有效-- 看不到变量?说明 setProperty 目标错了,或者变量名拼错导致被忽略(浏览器不报错)比如 mousemove 或 scroll 中频繁调用 setProperty,容易触发重排或丢帧:
requestAnimationFrame 节流,而不是 setTimeout 或裸循环--mouse-x-pct),CSS 里直接用 background-position: var(--mouse-x-pct)%,避免每次算像素偏移touchmove 里漏掉 e.preventDefault(),否则 iOS 会延迟触发,造成坐标滞后最常被忽略的是 fallback 和作用域——变量写了但没生效,八成是 var(--x) 后面缺了默认值,或者压根没挂到 :root 上。