scss不支持&&、||、!等布尔运算符,仅支持true/false布尔值参与@if、@else等编译时条件判断;所有逻辑必须在编译前确定,无法实现运行时动态切换。

SCSS里没有布尔运算,只有布尔值参与的条件判断
SCSS本身不支持 &&、||、! 这类 JavaScript 风格的布尔逻辑运算符。所谓“布尔运算对CSS逻辑控制很重要”,其实是误传——真正起作用的是 @if、@else、@each 等控制指令,配合变量类型(如 true/false)或函数返回值(如 type-of($val) == "bool")做分支处理。
常见错误现象包括:
- 直接写
$cond && $val导致编译报错:Error: Invalid CSS after "$cond": expected expression, was "&&" - 把
@if $flag == true当成 JS 习惯,其实@if $flag就够了(false、null、""、()才为假) - 在
calc()中混用插值和布尔值,比如width: calc(#{$w} * #{$enabled ? 1 : 0})—— SCSS 不支持三元操作符,会报错
@if 能做什么:主题开关与组件状态控制
@if 是 SCSS 中唯一能实现“条件渲染”效果的原生机制,适用于编译时确定的逻辑分支,比如深色模式开关、组件启用/禁用状态。
使用场景示例:
- 根据
$theme: dark或light输出不同颜色规则 - 当
$has-border: false时跳过border声明,减小最终 CSS 体积 - 在 mixin 中判断参数类型,避免传入字符串却当数字用
实操建议:
- 不要试图在样式属性值中动态拼接布尔结果,SCSS 不支持运行时求值
- 把判断提前到变量定义层,例如:
$border-width: if($has-border, 1px, 0) - 慎用嵌套
@if,超过两层易读性骤降;优先用 map +@each替代多分支
用 map 和 @each 模拟“条件循环渲染”
当需要批量生成一组带条件的样式(比如多个按钮变体),@each 配合 map 是比堆砌 @if 更可维护的方式。
示例:按状态生成不同背景色的按钮类
$btn-states: (
default: #3498db,
hover: #2980b9,
disabled: #bdc3c7,
active: #1abc9c
);
<p>@each $state, $color in $btn-states {
.btn-#{$state} {
background-color: $color;
@if $state == "disabled" {
cursor: not-allowed;
opacity: 0.6;
}
}
}</p>
注意点:
- map 的 key 必须是 unquoted(如
default),否则插值后变成.btn-"default",非法选择器 -
@each是编译期展开,不会产生运行时开销,但会增大输出 CSS 体积 - 无法在
@each内部修改外部 map,SCSS 变量不可变
真正该警惕的“伪布尔控制”陷阱
很多开发者试图用 CSS 自定义属性(--enabled: true)+ calc() + 插值模拟运行时布尔切换,这是危险的。
问题本质:
- SCSS 在构建时就完成了所有计算,
#{...}插值只展开一次,无法响应用户交互 - 浏览器不解析 SCSS,所有条件必须在编译前确定
- 把逻辑塞进 CSS 文件,违背关注分离原则;该由 JS 控制的状态不应硬编码进样式
正确分工:
- SCSS 负责“哪些样式存在”(编译时静态分支)
- CSS 自定义属性 + JS 负责“哪些样式生效”(运行时动态切换)
- 例如:用
:is([data-enabled="true"]) .btn配合 JS 切换data-enabled属性,比在 SCSS 里写一堆@if更灵活
最常被忽略的一点:SCSS 的“条件”不是给浏览器看的,是给开发者看的编译开关——它不解决运行时状态同步问题,也替代不了 class 切换或 CSS-in-JS 的响应能力。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











