🧩 一、CSS 变量的定义与使用基础
定义方式
css
:root {
--primary-color: #409eff;
--font-size-base: 14px;
}
:root 选择器相当于全局作用域(类似全局变量)。
使用方式
css
button {
color: var(--primary-color);
font-size: var(--font-size-base);
}
var() 语法:
css
color: var(--text-color, #333); /* 第二个参数是默认值 */
⚙️ 二、动态修改 CSS 变量(核心)
CSS 变量是运行时动态的,可以通过 JS 修改而立即生效,无需重新渲染整个页面。
✅ 方法 1:修改根节点变量
javascript
document.documentElement.style.setProperty('--primary-color', '#ff4d4f');
✅ 方法 2:修改某个局部作用域
CSS 变量有作用域,可以定义在某个元素上:
css
.card {
--card-bg: white;
background: var(--card-bg);
}
JS 动态改它:
dart
document.querySelector('.card').style.setProperty('--card-bg', '#f5f5f5');
🧭 三、灵活应用场景
1. 主题切换(暗色 / 亮色)
css
:root {
--bg-color: #fff;
--text-color: #000;
}
[data-theme="dark"] {
--bg-color: #121212;
--text-color: #fff;
}
JS 切换:
javascript
document.documentElement.setAttribute('data-theme', 'dark');
🔥 推荐做法:通过
data-theme或class切换主题,CSS 自己处理颜色映射。
2. 响应式设计 + 动态计算
利用 calc()、clamp() 等函数与变量结合:
css
:root {
--base-size: 16px;
}
.card {
font-size: calc(var(--base-size) * 1.2);
}
在 JS 中动态调整全局字号:
javascript
document.documentElement.style.setProperty('--base-size', '18px');
3. 组件参数化
在组件封装中(如 React / Vue / Web Components),可通过变量让组件样式可配置:
css
.my-button {
--btn-color: #409eff;
background-color: var(--btn-color);
}
父组件通过 style 传入:
ini
<MyButton style="--btn-color: #ff4d4f" />
4. 配合动画 / 动态过渡
CSS 变量可以和 transition 配合使用:
css
:root {
--panel-height: 100px;
}
.panel {
height: var(--panel-height);
transition: height 0.3s ease;
}
JS 动态修改:
javascript
document.documentElement.style.setProperty('--panel-height', '200px');
面板高度会平滑过渡。
🧠 四、CSS 变量 vs 预处理器变量(LESS/SASS)
| 特性 | CSS变量 | LESS/SASS变量 |
|---|---|---|
| 生效时机 | 运行时 | 编译时 |
| 动态修改 | ✅ 可运行时修改 | ❌ 需重新编译 |
| 可作用域化 | ✅ 有作用域(继承) | ❌ 全局或局部编译作用域 |
| 浏览器支持 | ✅ 现代浏览器全支持 | ✅ 依赖编译 |
💡 通常结合使用:
- LESS 变量负责 编译时样式结构
- CSS 变量负责 运行时动态主题
🧰 五、实践建议
-
定义命名规范:
css--color-primary --font-size-sm --layout-header-height -
建立统一入口文件:
variables.css管理所有变量,通过@import或构建工具引入。 -
避免滥用:
动态改动频繁的变量可使用 JS 样式或 class 切换,静态主题类变量用 CSS 变量即可。
-
可结合存储:
iniconst theme = 'dark'; localStorage.setItem('theme', theme); document.documentElement.dataset.theme = theme;
🎨 示例:多主题动态切换
xml
<style>
:root {
--bg: #fff;
--text: #000;
}
[data-theme='dark'] {
--bg: #1e1e1e;
--text: #fff;
}
body {
background: var(--bg);
color: var(--text);
transition: background 0.3s, color 0.3s;
}
</style>
<body>
<button id="toggleTheme">切换主题</button>
<script>
const root = document.documentElement;
document.getElementById('toggleTheme').onclick = () => {
const isDark = root.dataset.theme === 'dark';
root.dataset.theme = isDark ? 'light' : 'dark';
};
</script>
</body>