SCSS 的 @if 仅在编译时根据预注入变量静态判断,无法感知运行时环境;需通过构建工具(如 Webpack/Vite)提前注入 $env 值,否则报错;字符串比较须加引号,布尔判断注意真值规则,多条件需括号,调试用 @debug,真正环境区分靠构建输出多套CSS或JS运行时切换class。

SCSS 的 @if 指令无法“判断当前环境”,它只在编译时根据你提前注入的变量值决定输出哪部分 CSS —— 浏览器运行时、用户操作、CSS 变量、prefers-color-scheme 都不影响它。
为什么 @if $env == 'production' 看似有效,实则靠外部注入
你写的这行代码本身不读取任何运行时环境信息。它生效的前提是:$env 这个 Sass 变量必须在编译前就被明确赋值,比如:
- Webpack 用
DefinePlugin注入:把process.env.NODE_ENV映射为 Sass 变量$env: "production" - Vite 通过
define配置 +sass选项传入:css: { preprocessorOptions: { sass: { additionalData: '$env: "' + process.env.MODE + '";' } } } - 构建脚本手动替换:用
sed或cross-env在打包前写死_env.scss文件内容
如果没做这些,$env 就是未定义变量,Sass 编译直接报错 Undefined variable "$env"。
@if 判断字符串和布尔值的常见翻车点
即使变量已注入,类型和语法错误也会让分支失效:
立即学习“前端免费学习笔记(深入)”;
-
@if $env == "production"✅(字符串必须加双引号);@if $env == production❌(会被解析为变量名$production) -
@if $debug✅ 当$debug: true;但@if $debug对$debug: false或$debug: null才为假 —— 注意0、""、()全部算真值 - 多条件必须加括号:
@if ($env == "production") and ($theme == "dark"),漏括号会导致逻辑错乱 - 调试时加一行
@debug $env;,确认值和类型是否符合预期
真正能区分“当前环境”的方案只有两种
别指望 @if 自动感知环境,它只是个静态开关:
-
构建时差异化输出:用不同命令跑两次编译,例如
sass --define=env=production main.scss:dist/main.prod.css和--define=env=development,生成两套独立 CSS 文件 -
运行时切换靠 JS + class:Sass 里预编译好
.theme-dark {}和.theme-light {},JS 根据localStorage或matchMedia切换document.documentElement.className
混用时最容易忽略的是变量作用域 —— 如果你用 @use 引入模块,$env 必须在该文件中声明或通过命名空间访问,否则 @if 根本看不见它。


















