必须用:root声明CSS全局变量,因其是规范唯一认可的文档根锚点,确保全树继承、跨文档兼容且权重更高;html或body声明会导致作用域残缺、SSR失效或伪元素不可访问。

必须在 :root 中定义才能真正全局可用,否则 var() 调用大概率失效或回退到 fallback。
为什么一定要写 :root,而不是 html 或 body
:root 是伪类,匹配文档根元素,在 HTML 中等价于 html,但权重更高、解析更稳定,且在 SVG/Shadow DOM 等非标准上下文中仍能正确指向根节点。用 html 声明变量看似一样,但在某些预处理器嵌套或框架 scoped 样式中容易被覆盖;body 或其他元素声明则直接限制作用域——子元素能用,兄弟、父级、同级其他元素全不可见。
-
:root { --color: #007bff; }→ 整个页面任意位置var(--color)都有效 -
html { --color: #007bff; }→ 大部分情况可用,但部分构建工具或 Shadow DOM 场景下可能失效 -
body { --color: #007bff; }→ 只有body及其后代可访问,head里写的style或meta相关样式无法使用
var() 的 fallback 写法和常见翻车点
var() 第二个参数是纯 fallback,只在变量未定义、拼写错误或语法非法时触发,不是“备选变量”,也不支持嵌套调用。
- ✅ 正确:
color: var(--text-color, #333);—— 变量不存在时用#333 - ❌ 错误:
color: var(--text-color, var(--fallback));—— 第二个参数不解析var() - ❌ 错误:
margin: var(--space)px;—— 单位不能拼在外面,应让变量本身带单位,如--space: 12px;,再写margin: var(--space); - ⚠️ 多值 fallback(如
background: var(--bg, linear-gradient(...)))无需引号,但必须是合法 CSS 值;加引号反而导致无效
局部变量怎么用,什么时候该用
局部变量不是“错误”,而是明确的作用域控制手段,适合组件级隔离或主题覆盖。
立即学习“前端免费学习笔记(深入)”;
- 在组件选择器内定义:
.card { --card-bg: #f8f9fa; },那么只有.card及其子元素能用var(--card-bg) - 父子同名变量会自然覆盖:
:root { --color: blue; }+.section { --color: red; }→.section p里var(--color)得到red - JS 动态改局部变量:用
element.style.setProperty('--color', 'green'),只影响该元素及其后代,不影响全局 - 别在
class里重复定义同一变量名做“条件切换”,CSS 层叠规则会以后声明为准,逻辑易混乱;更适合用 JS 控制 class 切换或直接 setProperty
真正容易被忽略的是变量值的“完整性”——比如 --size: 16 缺单位,后续 font-size: var(--size) 就无效;又或者 --shadow: 0 2px 4px 没写颜色,默认透明,看起来像没生效。定义时就要让它本身是可直接使用的合法 CSS 值。


















