前端开发如何灵活使用 css 变量

190 阅读2分钟

🧩 一、CSS 变量的定义与使用基础

定义方式

:root {
  --primary-color: #409eff;
  --font-size-base: 14px;
}

:root 选择器相当于全局作用域(类似全局变量)。

使用方式

button {
  color: var(--primary-color);
  font-size: var(--font-size-base);
}

var() 语法:

color: var(--text-color, #333); /* 第二个参数是默认值 */

⚙️ 二、动态修改 CSS 变量(核心)

CSS 变量是运行时动态的,可以通过 JS 修改而立即生效,无需重新渲染整个页面。

✅ 方法 1:修改根节点变量

document.documentElement.style.setProperty('--primary-color', '#ff4d4f');

✅ 方法 2:修改某个局部作用域

CSS 变量有作用域,可以定义在某个元素上:

.card {
  --card-bg: white;
  background: var(--card-bg);
}

JS 动态改它:

document.querySelector('.card').style.setProperty('--card-bg', '#f5f5f5');

🧭 三、灵活应用场景

1. 主题切换(暗色 / 亮色)

:root {
  --bg-color: #fff;
  --text-color: #000;
}

[data-theme="dark"] {
  --bg-color: #121212;
  --text-color: #fff;
}

JS 切换:

document.documentElement.setAttribute('data-theme', 'dark');

🔥 推荐做法:通过 data-themeclass 切换主题,CSS 自己处理颜色映射。


2. 响应式设计 + 动态计算

利用 calc()clamp() 等函数与变量结合:

:root {
  --base-size: 16px;
}

.card {
  font-size: calc(var(--base-size) * 1.2);
}

在 JS 中动态调整全局字号:

document.documentElement.style.setProperty('--base-size', '18px');

3. 组件参数化

在组件封装中(如 React / Vue / Web Components),可通过变量让组件样式可配置:

.my-button {
  --btn-color: #409eff;
  background-color: var(--btn-color);
}

父组件通过 style 传入:

<MyButton style="--btn-color: #ff4d4f" />

4. 配合动画 / 动态过渡

CSS 变量可以和 transition 配合使用:

:root {
  --panel-height: 100px;
}

.panel {
  height: var(--panel-height);
  transition: height 0.3s ease;
}

JS 动态修改:

document.documentElement.style.setProperty('--panel-height', '200px');

面板高度会平滑过渡。


🧠 四、CSS 变量 vs 预处理器变量(LESS/SASS)

特性CSS变量LESS/SASS变量
生效时机运行时编译时
动态修改✅ 可运行时修改❌ 需重新编译
可作用域化✅ 有作用域(继承)❌ 全局或局部编译作用域
浏览器支持✅ 现代浏览器全支持✅ 依赖编译

💡 通常结合使用:

  • LESS 变量负责 编译时样式结构
  • CSS 变量负责 运行时动态主题

🧰 五、实践建议

  1. 定义命名规范:

    --color-primary
    --font-size-sm
    --layout-header-height
    
  2. 建立统一入口文件:
    variables.css 管理所有变量,通过 @import 或构建工具引入。

  3. 避免滥用:
    动态改动频繁的变量可使用 JS 样式或 class 切换,静态主题类变量用 CSS 变量即可。

  4. 可结合存储:

    const theme = 'dark';
    localStorage.setItem('theme', theme);
    document.documentElement.dataset.theme = theme;
    

🎨 示例:多主题动态切换

<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>