css自定义属性需在选择器(如:root)内用--前缀声明,通过var()函数使用,支持动态重写和深色模式适配,但不支持数学运算、ie11及svg内联引用,回退值仅在变量未定义或非法时生效。

怎么在CSS里定义和使用--primary-color这类变量
自定义属性(CSS Custom Properties)本质是带--前缀的变量,必须声明在CSS选择器作用域内,最常用的是挂在:root上——它等价于全局作用域,所有后代元素都能访问。
常见错误是直接写--primary-color: #007bff;却不加选择器,浏览器会忽略;或者误以为它像Sass变量一样能跨文件自动继承,其实必须确保样式表已加载且顺序正确。
- 定义写在
:root里::root { --primary-color: #007bff; --text-default: #333; } - 使用时必须搭配
var()函数:color: var(--text-default);,不能直接写color: --text-default; - 支持层叠和动态重写:在
.dark-theme里重新声明--primary-color,所有用var(--primary-color)的地方会自动响应 - 不支持CSS预处理器的数学运算,比如
var(--primary-color) * 0.8会报错,得用color-mix()或HSL调整
为什么var(--color, #ccc)的回退值有时不生效
回退值只在var()的第一个参数完全无效时才启用,比如变量名拼错、变量未定义、或变量值本身是非法CSS值(如--size: 12; 缺单位)。
但如果你写了--color: inherit;或--color: transparent;,哪怕语义上“没颜色”,只要语法合法,var(--color, #ccc)就绝不会用#ccc——它不判断语义,只校验是否可解析。
- 典型陷阱:
--bg: ;(空值)或--bg: undefined;(字符串)会导致回退触发;但--bg: none;是合法值,回退不触发 - 调试技巧:浏览器开发者工具里,失效的
var()会显示为invalid,悬停能看到具体原因 - 安全写法:对关键颜色,宁可重复定义也不依赖回退,比如
background: var(--surface-bg, #fff); color: var(--text-primary, #111);
怎样让CSS自定义属性适配深色模式切换
核心不是靠媒体查询“切换变量”,而是利用@media (prefers-color-scheme: dark)重定义同一组变量——所有引用这些变量的样式会自动更新,无需JS干预或重复写规则。
容易被忽略的是:如果深色模式逻辑复杂(比如用户手动开关+系统偏好+时间判断),纯CSS不够用,就得用document.documentElement.style.setProperty()动态改:root变量,此时要注意避免覆盖其他变量。
- 基础方案:
@media (prefers-color-scheme: dark) { :root { --text-primary: #e6e6e6; --surface-bg: #1a1a1a; } } - JS动态控制时,优先用
style.setProperty('--color', 'red')而非style.cssText,后者会清空已有内联样式 - 避免在
body或组件上重复定义同名变量,否则层级混乱,var()取值不可预测 - 动画限制:自定义属性本身不触发重绘,但若它驱动
background-color等可动画属性,需显式加transition: background-color 0.2s;
哪些场景下不该用CSS自定义属性管颜色
当颜色需要精确到像素级控制(比如SVG fill内联属性)、或要被JavaScript频繁读写并参与计算(如生成渐变色数组)、或项目还依赖IE11时,自定义属性就不合适了。
更隐蔽的问题是构建工具链:Vite/Webpack的CSS提取插件可能把:root变量抽到单独CSS文件,而JS里用getComputedStyle读取时,若该CSS尚未注入,就会得到空值。
- SVG内联颜色:直接写
fill="#007bff",别用fill="var(--primary)"(多数SVG渲染引擎不支持) - JS计算场景:用CSSOM读取
getComputedStyle(document.documentElement).getPropertyValue('--primary-color')成本高,不如维护一个JS对象映射 - 构建风险:Webpack的
mini-css-extract-plugin默认异步加载CSS,document.documentElement变量可能还没初始化 - 真正需要“一套颜色系统”的地方,变量只是载体,关键是建立命名约定(如
--color-brand-primary)和变更流程,否则变量越多越难维护
颜色系统最难的从来不是怎么写var(),而是谁有权改--color-error、改完要不要同步设计稿、暗色模式下--color-success的亮度差够不够无障碍标准——这些没法靠CSS解决。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











