前端开发中 SCSS 变量与 CSS 变量的区别与实践选择,—— 两种变量别混为一谈

一、SCSS 变量与 CSS 变量的本质区别

在 Vue 或任意前端项目中,我们经常同时使用 SCSSCSS 变量

它们的语法相似,但工作原理完全不同

对比维度 SCSS 变量 CSS 变量(自定义属性)
定义方式 $primary-color: #409EFF; --primary-color: #409EFF;
使用方式 color: $primary-color; color: var(--primary-color);
解析阶段 编译时(构建时由 Sass 替换) 运行时(由浏览器解析,可动态修改)
作用范围 Sass 文件内部或导入链内 CSS 层级继承(可以定义在 :root、类、标签中)
是否动态 ❌ 静态,构建后无法再改 ✅ 可通过 JS 或类名动态切换
浏览器支持 所有浏览器(最终是普通 CSS) 现代浏览器(IE 不支持)

二、特别注意:SCSS 变量写在 :root 中是无效的!

很多人初学时,会这样写:

css 复制代码
:root {
  $primary-color: #409eff;
}

然后希望这样用:

css 复制代码
.button {
  color: $primary-color;
}

结果:编译报错!或者变量根本不生效。

原因解释

  • SCSS 变量在编译阶段就会被处理掉 ,它不存在于最终生成的 CSS 文件中

  • Sass 预处理器在编译时根本不会识别 :root 内的 $变量,因为 $变量 并不是 CSS 属性。

换句话说:

$变量 是编译阶段的指令,而 :root 是运行时的选择器。

二者不在同一个阶段生效。

正确写法应该是:

css 复制代码
// variables.scss
$primary-color: #409eff;

.button {
  color: $primary-color;
}

或者如果你想让 CSS 在运行时也能读取到一个变量,就要用 CSS 自定义属性

css 复制代码
:root {
  --primary-color: #409eff;
}

.button {
  color: var(--primary-color);
}

三、在 Vue 项目中的使用注意事项

3.1 SCSS 变量:编译期常量,写在全局变量文件中即可

css 复制代码
// src/styles/variables.scss
$primary: #409eff;
$font-size-base: 14px;

然后在 vite.config.ts 中全局注入:

css 复制代码
css: {
  preprocessorOptions: {
    scss: {
      additionalData: `@import "@/styles/variables.scss";`
    }
  }
}

不需要 :root,也不应该放在 :root 中。

因为 $变量 只在 Sass 编译期存在,写在任何选择器里都不会影响结果。

3.2 CSS 变量:运行时变量,必须放在 :root 或具体选择器中

css 复制代码
:root {
  --color-primary: #409EFF;
}

.dark {
  --color-primary: #66b1ff;
}

.button {
  color: var(--color-primary);
}

SS 变量存在于运行时,可以通过 JavaScript 动态修改:

css 复制代码
document.documentElement.style.setProperty('--color-primary', '#ff0000');

四、如何结合使用两种变量?

实际开发中,两种变量往往结合使用,取长补短:

css 复制代码
// 使用 SCSS 计算和生成 CSS 变量
$theme-light: #fff;
$theme-dark: #000;

:root {
  --theme-light: #{$theme-light};
  --theme-dark: #{$theme-dark};
}

这样:

  • SCSS 负责计算和组织变量

  • CSS 变量负责在运行时控制主题

五、实践中的选型建议

场景 推荐使用
固定样式(颜色、间距、字号等) ✅ SCSS 变量
动态主题、暗黑模式 ✅ CSS 变量
响应式计算、尺寸比例 ✅ SCSS 变量
JS 需动态控制颜色 ✅ CSS 变量
组件库(既要暴露主题接口,又要可计算) 混合:SCSS 生成 CSS 变量

六、总结

SCSS 变量是编译期的计算逻辑,不需要、也不能放在 :root 中。

CSS 变量是运行期的样式变量,必须定义在 :root 或具体元素内。

二者一个属于"开发阶段",一个属于"浏览器阶段",

搞清楚它们的"时空位置",就不会再混淆。

相关推荐
ywf121544 分钟前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭1 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf7 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特7 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷7 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian8 小时前
前端node常用配置
前端
华洛8 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq8 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A9 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常9 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端