首页 / CSS 入门教程 / CSS 变量

CSS 入门教程

CSS 变量

本教程共 44 篇 · 第 42 篇 · 更新于 2026-07-29 · 约 12 分钟阅读

CSS变量var自定义属性主题切换作用域

42. CSS 变量

本节目标:理解 CSS 变量的概念,能够声明和使用变量,掌握作用域规则和变量覆盖,了解在媒体查询和 JavaScript 中操作变量的方法。

CSS 变量(自定义属性)让你把值存起来重复使用。改一处,所有用到的地方都跟着变。

声明变量

变量名以 -- 开头,赋值方式和普通属性一样:

:root {
  --main-color: #3498DB;
  --spacing: 16px;
  --font-stack: "Helvetica", sans-serif;
}

:root 选择器匹配文档的根元素(<html>)。在这里声明的变量就是全局变量,任何地方都能用。

变量名区分大小写。

--main-color 是两个不同的变量。

var() 函数

var() 函数读取变量的值:

.button {
  background-color: var(--main-color);
  padding: var(--spacing);
  font-family: var(--font-stack);
}

完整示例:

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    :root {
      --primary: #3498DB;
      --bg: #F5F5F5;
      --padding: 16px;
    }
    body {
      background: var(--bg);
      font-family: sans-serif;
      padding: var(--padding);
    }
    h1 { color: var(--primary); }
    .card {
      background: white;
      border-left: 4px solid var(--primary);
      padding: var(--padding);
      margin-bottom: var(--padding);
    }
  </style>
</head>
<body>
  <h1>CSS 变量示例</h1>
  <div class="card">卡片 1</div>
  <div class="card">卡片 2</div>
</body>
</html>

回退值

var() 第二个参数是回退值。变量未定义时,使用回退值:

color: var(--text-color, #333);
background: var(--bg-color, white);

还可以嵌套使用:

color: var(--primary, var(--fallback, #333));

回退值在组件开发中特别有用。组件定义默认值,使用时通过变量覆盖,不需要的值就用默认的。

作用域

变量有作用域,和普通编程语言类似:

全局变量:在 :root 中声明,整个文档可用。

局部变量:在某个选择器内声明,只在该选择器及其子元素中可用。

/* 全局变量 */
:root {
  --color: blue;
}

/* 局部变量 */
.alert {
  --color: red;
}

/* 这里 --color 是红色 */
.alert { color: var(--color); }

/* 这里 --color 是蓝色 */
.normal { color: var(--color); }
<!DOCTYPE html>
<html lang="zh">
<head>
  <style>
    :root { --color: blue; }
    .alert { --color: red; }
    .alert { color: var(--color); }
    .normal { color: var(--color); }
  </style>
</head>
<body>
  <p class="normal">蓝色文字(全局变量)</p>
  <p class="alert">红色文字(局部变量覆盖)</p>
</body>
</html>

变量覆盖

局部变量会覆盖同名的全局变量。利用这个特性,可以轻松实现主题切换:

:root {
  --bg: white;
  --text: #333;
  --primary: #3498DB;
}

/* 深色主题 */
.dark {
  --bg: #1a1a2e;
  --text: #eee;
  --primary: #00D2FF;
}

.themed {
  background: var(--bg);
  color: var(--text);
}

.themed h1 {
  color: var(--primary);
}
<!DOCTYPE html>
<html lang="zh">
<head>
  <style>
    :root {
      --bg: white;
      --text: #333;
      --primary: #3498DB;
    }
    .dark {
      --bg: #1a1a2e;
      --text: #eee;
      --primary: #00D2FF;
    }
    .themed {
      background: var(--bg);
      color: var(--text);
      padding: 20px;
      transition: all 0.3s;
    }
    .themed h1 { color: var(--primary); }
  </style>
</head>
<body>
  <div class="themed" id="content">
    <h1>主题切换演示</h1>
    <p>点击按钮切换主题</p>
  </div>
  <button onclick="document.getElementById('content').classList.toggle('dark')">切换主题</button>
</body>
</html>

变量覆盖是 CSS 主题切换的核心原理。给

加一个类名,所有变量跟着变,整个页面换肤。

在媒体查询中使用变量

变量配合媒体查询,能大幅简化响应式代码:

:root {
  --columns: 1;
  --font-size: 14px;
  --spacing: 8px;
}

@media (min-width: 768px) {
  :root {
    --columns: 2;
    --font-size: 16px;
    --spacing: 16px;
  }
}

@media (min-width: 1024px) {
  :root {
    --columns: 3;
    --font-size: 18px;
    --spacing: 24px;
  }
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--columns), 1fr);
  gap: var(--spacing);
  font-size: var(--font-size);
}
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    :root {
      --columns: 1;
      --font-size: 14px;
      --spacing: 8px;
    }
    @media (min-width: 768px) {
      :root {
        --columns: 2;
        --font-size: 16px;
        --spacing: 16px;
      }
    }
    @media (min-width: 1024px) {
      :root {
        --columns: 3;
        --font-size: 18px;
        --spacing: 24px;
      }
    }
    .grid {
      display: grid;
      grid-template-columns: repeat(var(--columns), 1fr);
      gap: var(--spacing);
      font-size: var(--font-size);
      padding: var(--spacing);
    }
    .item {
      background: #3498DB;
      color: white;
      padding: 20px;
      border-radius: 8px;
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="grid">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
  </div>
</body>
</html>

在 JavaScript 中操作变量

CSS 变量可以访问 DOM,所以能用 JavaScript 动态修改:

// 获取根元素
const root = document.documentElement;

// 读取变量
const primary = getComputedStyle(root).getPropertyValue('--primary');
console.log(primary); // 输出: #3498DB

// 设置变量
root.style.setProperty('--primary', '#E74C3C');
<!DOCTYPE html>
<html lang="zh">
<head>
  <style>
    :root { --primary: #3498DB; }
    .box {
      width: 100px;
      height: 100px;
      background: var(--primary);
      margin: 20px;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <div class="box"></div>
  <button onclick="changeColor()">换色</button>
  <script>
    function changeColor() {
      const colors = ['#3498DB', '#E74C3C', '#2ECC71', '#9B59B6', '#F39C12'];
      const random = colors[Math.floor(Math.random() * colors.length)];
      document.documentElement.style.setProperty('--primary', random);
    }
  </script>
</body>
</html>

设置的变量值会作为内联样式,优先级较高。如果需要覆盖,记得用 !important 或提高选择器特异性。

@property:高级变量定义

CSS 的 @property 规则可以给变量添加类型检查和默认值:

@property --my-color {
  syntax: "<color>";       /* 类型:颜色 */
  inherits: true;          /* 可继承 */
  initial-value: gray;     /* 默认值 */
}
参数说明
syntax数据类型:<color><length><number><percentage>
inherits是否可继承:truefalse
initial-value默认值
@property --gradient-start {
  syntax: "<color>";
  inherits: false;
  initial-value: #EADEDB;
}

@property --gradient-end {
  syntax: "<color>";
  inherits: false;
  initial-value: #BC70A4;
}

.hero {
  background: linear-gradient(var(--gradient-start), var(--gradient-end));
}
Tip

是较新的特性(Chrome 85+、Safari 16.4+、Firefox 128+)。生产环境使用前请确认浏览器兼容性。

变量 vs 预处理器

特性CSS 变量Sass/Less 变量
运行时可以动态修改编译后固定
作用域有(DOM 树决定)有(代码块决定)
媒体查询可以不可以
JavaScript可以读写不可以
兼容性IE 不支持都支持(编译后)

CSS 变量的最大优势是动态性。预处理器变量编译后就没了,CSS 变量在浏览器里活着,随时可以改。

变量速查

概念说明
--name变量声明,以双横线开头
var(--name)读取变量值
var(--name, fallback)带回退值的读取
:root全局作用域
选择器内声明局部作用域
setProperty()JavaScript 设置变量
@property类型检查和默认值定义

变量命名要有语义。

--blue 更好,因为主题色变了变量名不用改。--spacing-lg--space2 更好理解。