CSS 变量(自定义属性)
CSS 变量(也称为自定义属性)是 CSS3 引入的强大特性,它允许你在 CSS 中定义可复用的值,并在整个样式表中使用。CSS 变量让样式管理变得更加灵活和可维护。
为什么需要这个特性
在 CSS 变量出现之前,如果你想要在整个网站中使用相同的颜色、字体大小等值,你需要:
- 重复定义:在每个需要的地方重复写相同的值
- 难以维护:要修改时需要在多个地方修改
- 容易出错:可能遗漏某些地方,导致样式不一致
/* 没有 CSS 变量时 */
.button-primary {
background-color: #007bff;
color: white;
}
.link {
color: #007bff;
}
.border {
border-color: #007bff;
}
/* 要修改主色,需要在多个地方修改 */
有了 CSS 变量,你可以:
- 集中管理:在一个地方定义值
- 易于维护:修改一处即可影响所有使用的地方
- 动态更新:可以通过 JavaScript 动态修改
- 作用域控制:可以在不同作用域定义不同的值
/* 使用 CSS 变量 */
:root {
--primary-color: #007bff;
}
.button-primary {
background-color: var(--primary-color);
}
.link {
color: var(--primary-color);
}
/* 只需修改一处 */
核心概念解释
定义变量
CSS 变量以两个连字符(--)开头,定义在某个选择器中:
:root {
--primary-color: #007bff;
--font-size-base: 16px;
--spacing-unit: 8px;
}
命名规范:
- 使用两个连字符(
--)开头 - 使用有意义的名称
- 使用 kebab-case(短横线命名)
使用变量
使用 var() 函数来引用变量:
.element {
color: var(--primary-color);
font-size: var(--font-size-base);
padding: var(--spacing-unit);
}
变量作用域
CSS 变量有作用域,遵循 CSS 的层叠规则:
/* 全局变量(根元素) */
:root {
--color: blue;
}
/* 局部变量(特定元素) */
.container {
--color: red; /* 覆盖全局变量 */
}
/* 使用变量 */
.element {
color: var(--color); /* 在 .container 内是红色,其他地方是蓝色 */
}
默认值
var() 函数可以接受第二个参数作为默认值:
.element {
color: var(--primary-color, blue); /* 如果变量不存在,使用 blue */
padding: var(--spacing, 10px); /* 如果变量不存在,使用 10px */
}
常见用法
1. 颜色系统
建立统一的颜色系统:
:root {
/* 主色 */
--color-primary: #007bff;
--color-primary-dark: #0056b3;
--color-primary-light: #66b3ff;
/* 辅助色 */
--color-success: #28a745;
--color-danger: #dc3545;
--color-warning: #ffc107;
/* 中性色 */
--color-text: #333;
--color-text-light: #666;
--color-text-lighter: #999;
--color-bg: #fff;
--color-bg-light: #f5f5f5;
}
2. 间距系统
建立统一的间距系统:
:root {
--spacing-unit: 8px;
--spacing-xs: calc(var(--spacing-unit) * 0.5); /* 4px */
--spacing-sm: var(--spacing-unit); /* 8px */
--spacing-md: calc(var(--spacing-unit) * 2); /* 16px */
--spacing-lg: calc(var(--spacing-unit) * 3); /* 24px */
--spacing-xl: calc(var(--spacing-unit) * 4); /* 32px */
}
3. 字体系统
建立统一的字体系统:
:root {
--font-family-base: "Helvetica Neue", Arial, sans-serif;
--font-family-heading: "Georgia", serif;
--font-family-code: "Courier New", monospace;
--font-size-base: 16px;
--font-size-sm: 14px;
--font-size-lg: 18px;
--font-size-xl: 20px;
--line-height-base: 1.6;
--line-height-heading: 1.2;
}
4. 响应式变量
使用媒体查询创建响应式变量:
:root {
--container-width: 1200px;
--font-size-base: 16px;
}
@media (max-width: 768px) {
:root {
--container-width: 100%;
--font-size-base: 14px;
}
}
5. 主题切换
使用 CSS 变量实现主题切换:
/* 亮色主题 */
:root {
--bg-color: #fff;
--text-color: #333;
--border-color: #ddd;
}
/* 暗色主题 */
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #fff;
--border-color: #444;
}
/* 使用变量 */
body {
background-color: var(--bg-color);
color: var(--text-color);
}
示例
示例 1:设计系统
:root {
/* 颜色 */
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
/* 间距 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
/* 字体 */
--font-size-base: 16px;
--font-size-h1: 2.5rem;
--font-size-h2: 2rem;
/* 其他 */
--border-radius: 4px;
--box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.button {
background-color: var(--color-primary);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
font-size: var(--font-size-base);
}
.card {
padding: var(--spacing-lg);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
}
示例 2:动态主题
<button onclick="toggleTheme()">切换主题</button>
<div class="card">卡片内容</div>
:root {
--bg-color: #fff;
--text-color: #333;
--card-bg: #f5f5f5;
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #fff;
--card-bg: #2a2a2a;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s, color 0.3s;
}
.card {
background-color: var(--card-bg);
padding: 20px;
border-radius: 8px;
}
function toggleTheme() {
const html = document.documentElement;
const currentTheme = html.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', newTheme);
}
示例 3:组件变体
:root {
--button-padding: 10px 20px;
--button-radius: 4px;
}
.button {
padding: var(--button-padding);
border-radius: var(--button-radius);
}
.button-large {
--button-padding: 15px 30px;
--button-radius: 8px;
}
.button-small {
--button-padding: 5px 10px;
--button-radius: 2px;
}
示例 4:计算值
:root {
--base-size: 16px;
--spacing: 8px;
}
.element {
font-size: var(--base-size);
padding: calc(var(--spacing) * 2); /* 16px */
margin: calc(var(--spacing) * 3); /* 24px */
}
注意事项
1. 变量名区分大小写
CSS 变量名是区分大小写的:
:root {
--color: blue;
--Color: red; /* 这是不同的变量 */
}
2. 变量值可以是任何 CSS 值
变量值可以是颜色、长度、字符串等:
:root {
--color: #007bff;
--size: 16px;
--font: "Arial", sans-serif;
--shadow: 0 2px 4px rgba(0,0,0,0.1);
}
3. 变量可以继承
CSS 变量会继承,子元素可以使用父元素的变量:
.container {
--color: blue;
}
.container .element {
color: var(--color); /* 可以使用父元素的变量 */
}
4. 变量不能用于属性名
变量只能用于属性值,不能用于属性名:
/* 错误 */
:root {
--prop: color;
}
.element {
var(--prop): blue; /* 无效 */
}
/* 正确 */
:root {
--color: blue;
}
.element {
color: var(--color); /* 有效 */
}
5. 浏览器兼容性
CSS 变量在现代浏览器中支持良好,但旧版浏览器不支持:
/* 提供降级方案 */
.element {
color: blue; /* 降级方案 */
color: var(--primary-color, blue); /* 使用变量 */
}
6. 性能考虑
CSS 变量的性能很好,但过度使用可能影响性能:
/* 合理使用 */
:root {
--primary-color: #007bff;
}
/* 避免过度嵌套计算 */
.element {
padding: calc(calc(var(--base) * 2) + calc(var(--offset) * 3)); /* 不推荐 */
}
小结
CSS 变量是强大的样式管理工具:
- 定义:使用
--变量名: 值;定义 - 使用:使用
var(--变量名)引用 - 作用域:遵循 CSS 层叠规则
- 默认值:
var(--变量名, 默认值)
优势:
- 集中管理样式值
- 易于维护和修改
- 支持动态更新
- 实现主题切换
注意事项:
- 变量名区分大小写
- 变量值可以是任何 CSS 值
- 变量可以继承
- 变量不能用于属性名
- 考虑浏览器兼容性
掌握了 CSS 变量,你就能创建更加灵活和 可维护的样式系统。在下一章,我们将学习 CSS 函数,了解如何使用各种 CSS 函数来创建动态样式。