css自定义变量作用域由dom继承链决定,而非css优先级;var(--x)取值始终是向上最近的有效声明,:root仅作为全局默认值,局部声明需直接挂载目标或其父容器上。

它根本没覆盖——你看到的“覆盖”其实是误解了变量查找机制。:root 里定义的变量只是默认值,真正起效的是离 var(--x) 最近的那个声明。
为什么你以为 :root 覆盖了局部样式?
常见错觉来源:你在某个按钮上写了 button { --color: red; },但页面上颜色还是 :root 里设的蓝色。这不是 :root “赢了”,而是你的局部声明压根没生效——可能因为选择器没匹配到元素,或者被更外层同名声明“遮住”了。
-
button选择器只影响直接匹配的 button 元素,不自动影响其子 span 或 i 标签(除非它们显式用了var(--color)) - 如果父容器(比如
.card)也声明了--color,且该容器包裹了 button,那 button 内部读到的就是.card的值,不是你写的button值——因为 DOM 继承链上.card更近 -
:root { --color: blue; }永远只在上生效,写在其他选择器里(如.btn:hover { :root { --color: red; } })是无效语法,整条规则会被浏览器忽略
局部变量声明必须直接挂在目标容器上
想让某组按钮用绿色背景,不能靠提高选择器权重或往 :root 里塞新值,得把变量明确定义在它自己或它的直接父容器上:
- ✅ 正确:
.btn-success { --bg: #28a745; }→ 所有带这个类的按钮及其子元素读var(--bg)都取绿色 - ✅ 正确:
#sidebar .btn { --bg: #6c757d; }→ 仅侧边栏内的按钮受影响 - ❌ 错误:
button:hover { --bg: #28a745; }→ 这个声明只对::before/::after伪元素生效,button 内部文字、图标不会继承 - ❌ 错误:
.btn { :root { --bg: #28a745; } }→ 语法非法,浏览器直接丢弃整条规则
变量查找不看 CSS 优先级,只看 DOM 继承链
var(--x) 的值永远来自“向上最近的有效声明”,和选择器权重、源码顺序、是否加 !important 完全无关:
:root { --text: #333; }.section-a { --text: #222; }.section-a .card { --text: #111; }-
<div class="section-a"><div class="card"><p>hello</p></div></div>→p里var(--text)取#111,不是#222,更不是#333 - 哪怕你把
:root规则写在最后,只要它在.card外面,就不会干扰.card内部的值
最容易被忽略的一点:变量声明本身不触发重绘,只有使用它的属性(比如 color: var(--text))才会。所以改了 --text 却没看到变化,先检查是不是漏写了 var() 调用,而不是怀疑作用域失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











