SCSS 的 @if 仅在编译时识别手动注入的字符串变量,不支持运行时平台检测;必须通过 CLI、Webpack 或 Vite 显式传入带引号的 $platform 值(如 "ios"),并用 @mixin 封装平台逻辑以避免重复和作用域冲突。

SCSS 的 @if 无法识别运行时平台,只认你传进去的字符串
你在 @if $platform == "ios" 里写的判断,根本不会读取 navigator.platform 或 UA 字符串。Sass 编译器连浏览器进程都没启动,它只认构建时你手动塞进来的变量值。所谓“输出不同平台 CSS”,本质是:你提前告诉 Sass “这次编译目标是 iOS”,它就只保留 @if $platform == "ios" 分支里的样式,其余全丢弃。
必须用构建工具显式注入 $platform 变量,否则直接报错
常见错误是写完 @if $platform == "android" 却没在任何地方定义 $platform,Sass 直接抛 Undefined variable "$platform"。实操必须选一种方式注入:
- CLI:
sass --define=platform="ios" src/main.scss dist/ios.css - Webpack + sass-loader:
additionalData: '$platform: "android";'(注意加引号) - Vite:
css.preprocessorOptions.sass.define = { platform: JSON.stringify("web") }
别指望 process.env.PLATFORM 自动透传——Sass 不解析 JS 环境变量,必须显式转成字符串再注入。
字符串比较必须带双引号,且大小写敏感
@if $platform == ios 会报错,因为 Sass 把 ios 当作未声明变量;@if $platform == "IOS" 也不会命中 "ios"。正确写法只有:
立即学习“前端免费学习笔记(深入)”;
-
@if $platform == "ios"✅ -
@if $platform == "android"✅ -
@if $platform == "web"✅
建议在条件块前加一行 @debug $platform;,确认值和类型是否符合预期。漏掉 @else 会导致非匹配平台的样式彻底消失,不是留空,是不生成任何 CSS。
平台差异逻辑应封装进 @mixin,避免散落各处
别在每个按钮、弹窗里都写一遍 @if $platform == "ios"。把平台相关行为收进可复用的混合宏:
@mixin safe-area-padding {
@if $platform == "ios" {
padding-top: env(safe-area-inset-top);
}
@else if $platform == "android" {
padding-top: 24px;
}
@else {
padding-top: 16px;
}
}
这样调用时干净:.header { @include safe-area-padding; }。如果还要支持 iPadOS 或鸿蒙,新增 @else if $platform == "ipados" 即可,不用改业务样式代码。
真正容易被忽略的是变量作用域冲突——比如你用 @use "vars" 引入了 vars.$platform,又通过 CLI 传入 --define=platform="ios",后者会静默覆盖前者,且不报错。调试时务必确认 @debug $platform 输出的是你预期的那个值。


















