什么是CSS变量?
CSS变量(也称为自定义属性)是CSS3中的一个重要特性,允许您在样式表中存储值,并在整个文档中重复使用这些值。这大大提高了CSS的可维护性、灵活性和主题化能力。
CSS变量的优势:
- 提高代码的可维护性
- 轻松实现主题切换
- 减少代码重复
- 支持JavaScript动态修改
- 提高开发效率
- 支持响应式设计
浏览器支持
CSS变量在现代浏览器中得到了广泛支持:
Chrome
49.0+
Firefox
31.0+
Safari
9.1+
Edge
15.0+
IE
不支持
定义和使用CSS变量
定义变量
使用两个连字符(--)作为前缀来定义变量:
CSS
:root {
--primary-color: #82255E;
--secondary-color: #B83B6A;
--spacing: 1rem;
--border-radius: 10px;
--font-family: "微软雅黑", sans-serif;
--transition: all 0.3s ease;
}
使用变量
使用var()函数来引用变量:
CSS
.button {
background-color: var(--primary-color);
padding: var(--spacing);
border-radius: var(--border-radius);
font-family: var(--font-family);
transition: var(--transition);
}
变量命名规范
为了保持代码的可读性和一致性,建议遵循以下命名规范:
- 使用有意义的名称
- 使用kebab-case(短横线分隔)命名法
- 使用语义化名称而不是具体值
- 考虑命名空间,特别是对于大型项目
CSS
/* 好的命名 */
:root {
--color-primary: #82255E;
--spacing-small: 0.5rem;
--font-size-heading: 2rem;
}
/* 不好的命名 */
:root {
--color1: #82255E; /* 没有意义 */
--smallSpacing: 0.5rem; /* 不使用kebab-case */
}
变量作用域
CSS变量遵循CSS的层叠规则,可以在不同作用域中定义和覆盖:
CSS
/* 全局变量 */
:root {
--primary-color: blue;
}
/* 组件级变量 */
.component {
--primary-color: red;
background-color: var(--primary-color);
/* 使用红色,而不是蓝色 */
}
/* 元素级变量 */
.special-element {
--primary-color: green;
}
使用全局变量
使用局部变量(覆盖全局变量)
使用另一个局部变量
作用域继承
CSS变量具有继承性,子元素会继承父元素的变量值:
CSS
.parent {
--text-color: red;
}
.child {
color: var(--text-color); /* 继承父元素的 --text-color */
}
回退值
var()函数可以接受一个回退值,当变量未定义时使用:
CSS
.element {
background-color: var(--custom-color, blue);
/* 如果--custom-color未定义,使用蓝色 */
padding: var(--spacing, 10px 20px);
/* 如果--spacing未定义,使用10px 20px */
font-size: var(--font-size, var(--base-font-size, 16px));
/* 嵌套回退值 */
}
使用回退值(--undefined-color未定义,回退到--secondary-color)
注意: 回退值只在变量未定义时使用。如果变量已定义但值为无效值(如无效的颜色值),回退值不会被使用。
在calc()中使用变量
CSS变量可以与calc()函数结合使用,进行动态计算:
CSS
:root {
--base-size: 16px;
--spacing-multiplier: 2;
--header-height: 60px;
}
.element {
font-size: calc(var(--base-size) * 1.5);
margin: calc(var(--base-size) * var(--spacing-multiplier));
height: calc(100vh - var(--header-height));
}
这个元素的字体大小是24px,外边距是32px
使用JavaScript操作CSS变量
CSS变量可以通过JavaScript动态修改,这使得实时主题切换和动态样式成为可能:
JavaScript
// 获取根元素
const root = document.documentElement;
// 设置变量值
root.style.setProperty('--primary-color', '#ff0000');
// 获取变量值
const primaryColor = getComputedStyle(root)
.getPropertyValue('--primary-color');
// 移除变量
root.style.removeProperty('--primary-color');
// 批量设置变量
const theme = {
'--primary-color': '#82255E',
'--secondary-color': '#B83B6A',
'--spacing': '1rem'
};
Object.keys(theme).forEach(key => {
root.style.setProperty(key, theme[key]);
});
响应式变量更新
可以使用JavaScript监听事件并动态更新CSS变量:
JavaScript
// 根据窗口大小更新变量
function updateSpacing() {
const width = window.innerWidth;
const spacing = width > 1200 ? '2rem' : width > 768 ? '1.5rem' : '1rem';
document.documentElement.style.setProperty('--spacing', spacing);
}
// 监听窗口大小变化
window.addEventListener('resize', updateSpacing);
updateSpacing(); // 初始化
CSS变量演示
主题变量
样式变量
CSS变量效果演示
1
主要演示元素
使用: var(--demo-primary)
间距: var(--demo-spacing)
间距: var(--demo-spacing)
2
次要演示元素
使用: var(--accent-color)
圆角: var(--demo-radius)
圆角: var(--demo-radius)
3
自定义变量元素
局部变量: #B83B6A
阴影: var(--demo-shadow)
阴影: var(--demo-shadow)
当前CSS变量代码
CSS
:root {
--demo-primary: #82255E;
--demo-spacing: 16px;
--demo-radius: 5px;
--demo-shadow: 5px;
--demo-font-size: 16px;
}
实际应用示例
主题切换
CSS
/* 默认主题 */
:root {
--bg-color: #ffffff;
--text-color: #333333;
--primary-color: #82255E;
--border-color: #e0e0e0;
}
/* 暗色主题 */
.dark-theme {
--bg-color: #333333;
--text-color: #ffffff;
--primary-color: #B83B6A;
--border-color: #555555;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
.card {
background-color: var(--bg-color);
border: 1px solid var(--border-color);
}
响应式设计
CSS
:root {
--spacing: 1rem;
--font-size: 16px;
--columns: 1;
}
@media (min-width: 768px) {
:root {
--spacing: 2rem;
--font-size: 18px;
--columns: 2;
}
}
@media (min-width: 1200px) {
:root {
--spacing: 3rem;
--font-size: 20px;
--columns: 3;
}
}
.grid {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
gap: var(--spacing);
}
组件样式
CSS
.card {
--card-padding: 1rem;
--card-radius: 8px;
--card-shadow: 0 2px 4px rgba(0,0,0,0.1);
--card-bg: white;
padding: var(--card-padding);
border-radius: var(--card-radius);
box-shadow: var(--card-shadow);
background-color: var(--card-bg);
}
.card.large {
--card-padding: 2rem;
}
.card.dark {
--card-bg: #333;
--card-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
CSS变量与Sass/Less变量对比
CSS变量与预处理器变量有本质区别:
| 特性 | CSS变量 | Sass/Less变量 |
|---|---|---|
| 作用域 | 运行时,遵循CSS层叠 | 编译时,遵循预处理器作用域规则 |
| 动态性 | 可以通过JavaScript动态修改 | 编译后固定,无法修改 |
| 浏览器支持 | 现代浏览器支持 | 所有浏览器(编译为CSS后) |
| 使用场景 | 主题切换、动态样式 | 代码复用、计算、混入 |