:root特异性严格高于html,为(0,1,0)>(0,0,1),故所有冲突属性均被:root覆盖,即使html加!important也无效;其是CSS变量唯一规范锚点,且跨文档兼容SVG/XML/Shadow DOM。

:root 的特异性严格高于 html,不是“差不多”,而是明确的 (0,1,0) > (0,0,1) —— 所有冲突属性都会被 :root 覆盖,哪怕 html 声明加了 !important。
为什么 :root 会压过 html { ... !important }
这不是浏览器 bug,而是 CSS 优先级计算规则决定的::root 属于伪类选择器(Level 3),html 是类型选择器(Level 1)。当特异性数值逐位比较时,(0,1,0) 的第二位是 1,而 (0,0,1) 的第二位是 0,直接判负。即使 html { color: red !important; } 写在后面,:root { color: blue; } 依然生效——!important 只能提升声明级别,不能改变选择器本身的特异性权重。
用错地方最常导致变量覆盖失效
CSS 变量(--xxx)的读取依赖继承链起点是否“可达”。虽然技术上你能在 html 或 body 里声明变量,但只有 :root 是规范指定的全局锚点:
-
:root { --color-brand: #007bff; }→ 全局任意位置var(--color-brand)都能取到 -
html { --color-brand: #007bff; }→ 大部分情况也能用,但某些构建工具(如 PostCSS 自定义属性插件)默认只扫描:root下的声明 -
body { --color-brand: #007bff; }→header、footer等同级元素无法继承该变量
非 HTML 文档中 html 选择器彻底失效
当你给 SVG 内联样式、XML 文档或 Shadow DOM 设置主题色时,html 根本不匹配任何节点:
-
:root { --stroke: #333; }→ 在 SVG 中命中,在 HTML 中命中 -
html { --stroke: #333; }→ 在 SVG 中完全不生效,CSS 规则被忽略 - Web Components 中若使用
:host+:root组合,也能确保变量注入到 Shadow Root 的根作用域
IE9 是唯一需要权衡兼容性的边界
如果你的项目仍需支持 IE9,:root 是安全的(IE9+ 支持);但若要兼容 IE8 及更早版本,就必须放弃 :root,改用 html 并配合 JS 模拟变量机制。不过注意:IE8 不支持 var(),所以变量本身也无法使用——此时讨论选择器优先级已无实际意义。
真正容易被忽略的是:当你在第三方 UI 库的 CSS 文件里看到 html 声明了字体大小或重置样式,又在自己项目里用 :root 覆盖,可能连调试面板都看不出问题——因为 computed 值来源显示为 :root,但你根本没意识到库的 html 规则已被静默压制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











