CSS变量(也称为CSS自定义属性)是现代CSS中的一项强大特性,允许你定义可重用的值,并在整个样式表中引用它们。

一、基本概念
  • CSS 变量(自定义属性)是定义在 CSS 中的键值对,键以短破折号-- 开头,值可在样式中通过 var 函数引用。

  • 变量参与层叠与继承,能根据选择器范围、伪类、媒体查询等动态变化。

  • 适合做主题色、间距、字体尺寸等设计令牌的统一管理与切换。

二、基本语法
  • 定义:--name: value;

  • 使用:var(--name),可带回退值:var(--name, fallback)。

:root {
  --primary-color: #3b82f6;
  --spacing: 12px;
}

button {
  color: var(--primary-color);
  padding: var(--spacing);
}

/* 回退值 */
.card {
  border-color: var(--card-border, #ddd);
}
三、作用域与继承
  • 定义在 :root 的变量为全局变量。

  • 在某个选择器内定义的变量只对其子元素生效,并会被更近的定义覆盖。

:root { 
    --gap: 16px; 
}
.list { 
    --gap: 8px; 
}
.list .item { 
    /* 使用 8px */
    margin-bottom: var(--gap); 
}
.page .item { 
    /* 使用 16px */
    margin-bottom: var(--gap); 
}
四、动态性
  • 可响应状态与媒体条件。

:root { 
    --bg: #fff; 
}
@media (prefers-color-scheme: dark) {
    :root { 
        --bg: #0b0f19; 
    }
}
body { 
    background: var(--bg); 
}

  • 与预处理器变量不同,CSS变量可以在运行时通过JavaScript动态更新。

document.documentElement.style.setProperty('--primary-color', '#22c55e');
五、与预处理器变量的区别
  • Sass/Less 变量在编译时替换,不能在运行时改变,也不参与层叠/继承。

  • CSS 变量在浏览器运行时生效,可与 DOM 状态、媒体查询、用户交互联动。

六、回退值

可以在 var() 函数中提供回退值,当变量未定义时使用。

回退值,亦可称之默认值,指的是在引用一个未定义变量时,系统自动采用的替代值,以确保程序的稳定运行。

.element {
  background-color: var(--undefined-color, #f0f0f0);
}
七、常见用法
  • 主题切换:在不同主题类或 :root 中定义一组令牌。

  • 设计令牌:颜色、间距、圆角、阴影统一管理。

  • 组件参数化:组件根上定义变量,内部用 var() 引用。

  • 与 calc() 组合。

:root { 
    --base: 8px; 
}
.box { 
    padding: calc(var(--base) * 2); 
}
八、优势
  1. 维护性:改变一个变量值就能影响所有使用它的地方。

  2. 灵活性:可根据媒体查询或用户交互动态改变。

  3. 减少重复:避免在多处使用相同的硬编码值。

  4. 主题切换:轻松实现亮/暗主题或品牌主题切换。

  5. 响应式设计:结合媒体查询创建响应式变量。

九、实际应用示例
9.1 主题切换
/* 基础主题 */
:root {
  --bg-color: white;
  --text-color: black;
}

/* 暗色主题 */
[data-theme="dark"] {
  --bg-color: #333;
  --text-color: white;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: all 0.3s ease;
}
9.2 响应式设计
:root {
  --container-width: 1200px;
}

@media (max-width: 768px) {
  :root {
    --container-width: 90%;
  }
}

.container {
  width: var(--container-width);
  margin: 0 auto;
}
十、浏览器兼容性与注意
  • CSS变量得到了所有现代浏览器的良好支持,包括Chrome、Firefox、Safari和Edge。不支持IE10及以下版本。

  • 为关键变量提供回退值。

  • 使用可读的命名(如 --color-primary、--space-md)。

  • 将全局令牌放到 :root,组件级变量放到组件根选择器。

如需了解更多兼容性信息,建议访问《Can I Use》官网进行查询,内容全面,便于参考。

十一、示例:将全局令牌放到 :root,组件级变量放到组件根选择器

全局令牌 - 在:root中定义

/* 全局令牌 - 在:root中定义 */
:root {
  /* 颜色系统 */
  --color-primary: #1890ff;
  --color-success: #52c41a;
  --color-warning: #faad14;
  --color-error: #f5222d;
  
  /* 间距系统 */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  
  /* 字体系统 */
  --font-size-xs: 12px;
  --font-size-sm: 14px;
  --font-size-md: 16px;
  --font-size-lg: 18px;
}

按钮组件 - 组件级变量

/* 按钮组件 - 组件级变量 */
.btn {
  /* 组件特定变量,使用全局令牌作为基础 */
  --btn-bg-color: var(--color-primary);
  --btn-text-color: #ffffff;
  --btn-border-radius: 4px;
  --btn-padding: var(--spacing-sm) var(--spacing-md);
  --btn-font-size: var(--font-size-md);
  
  /* 使用组件变量 */
  background-color: var(--btn-bg-color);
  color: var(--btn-text-color);
  border-radius: var(--btn-border-radius);
  padding: var(--btn-padding);
  font-size: var(--btn-font-size);
  border: none;
  cursor: pointer;
}

按钮变体 - 重新定义组件变量

/* 按钮变体 - 重新定义组件变量 */
.btn--secondary {
  --btn-bg-color: #f0f0f0;
  --btn-text-color: #333333;
}

.btn--small {
  --btn-padding: var(--spacing-xs) var(--spacing-sm);
  --btn-font-size: var(--font-size-xs);
}

卡片组件 - 另一个组件的变量

/* 卡片组件 - 另一个组件的变量 */
.card {
  --card-bg-color: #ffffff;
  --card-border-color: #e8e8e8;
  --card-border-radius: 8px;
  --card-padding: var(--spacing-md);
  --card-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  
  background-color: var(--card-bg-color);
  border: 1px solid var(--card-border-color);
  border-radius: var(--card-border-radius);
  padding: var(--card-padding);
  box-shadow: var(--card-shadow);
}
总结

掌握CSS变量的定义、使用及动态更新技巧后,开发者能构建出高度模块化和灵活的样式系统。这将显著提升代码的可维护性(一处修改,全局生效),轻松实现主题切换响应式设计,并通过JavaScript实现交互逻辑与样式的深度联动,从而减少重复代码,降低开发与维护成本。