sass 的 @if、@for、@each 指令需严格遵循编译期静态求值规则:@if 仅支持布尔等原生判断,不支持三等号或运行时函数;@for 的 through/to 边界易错且无 break/continue;@each 对 list/map 类型敏感,空值静默跳过;所有变量默认全局作用域,需用 !local 避免污染。

@if 在 Sass 中怎么写才不报错
直接用 @if 没问题,但常见错误是把 JavaScript 那套逻辑搬过来——比如写 @if (condition === true) 或漏掉括号。Sass 的 @if 只接受布尔值、空值(null)、空列表、空 map 等原生判断,不支持三等号或函数调用当条件(除非返回布尔)。
实际用法要盯住两点:一是条件表达式必须能静态求值(编译期确定),二是分支必须用 @else 或 @else if 显式收尾,不能只写一个 @if 就结束。
- 正确写法:
@if $theme == dark { color: #000; } - 别写
@if $width > 1200px——单位不能直接参与数值比较,得先用unitless($width)剥离单位 - 嵌套时注意作用域:变量在
@if块内声明,外部不可见;想复用得提前定义或用!global
@for $i from 1 through 10 的边界和性能影响
@for 看似简单,但“through”和“to”的区别常被忽略:前者包含终点,后者不包含。比如 @for $i from 1 to 4 只循环 1、2、3;而 @for $i from 1 through 4 是 1、2、3、4。错用会导致生成类名少一个或样式错位。
更关键的是性能——Sass 编译器会在编译时展开全部循环,100 次循环就生成 100 段 CSS,毫无运行时优化。它不是 JS 的 for 循环,没“提前退出”概念(break 不存在),也没“跳过本次”(continue 不支持)。
立即学习“前端免费学习笔记(深入)”;
- 别用
@for处理动态数据,比如从 JSON 读配置;它只适合固定范围的样式生成(如栅格列宽、z-index 层级) - 避免嵌套多层
@for,3 层 × 各 10 次 = 1000 行 CSS,编译慢且难以调试 - 起始值和结束值必须是数字,
@for $i from $min to $max要确保 $min 和 $max 都已赋值且为数字,否则报错"$min" is not a number
@each 处理 map 和 list 时的类型陷阱
@each 最容易栽在数据结构上:传入 list 时,变量拿到的是每个元素本身;传入 map 时,要用两个变量(@each $key, $value in $map),顺序不能颠倒。如果 map 的 value 是嵌套结构,比如 (primary: (light: #e3f2fd, dark: #1565c0)),那 $value 就是个新 map,得再套一层 @each 才能解构。
另一个坑是空值处理:@each 遇到 null、空 list 或空 map 会直接跳过整个块,不报错也不执行——看着像没生效,其实是被静默忽略了。
- 检查数据前先用
length($list)或map-keys($map)确认非空,尤其当数据来自配置文件或 mixin 参数时 - 别对
@each $item in 1 2 3这种无括号 list 依赖——Sass 会把它当三个独立参数,应写成(1, 2, 3) - map 的 key 如果含破折号(如
font-size),引用时得加引号:map-get($config, "font-size"),否则解析失败
三个指令混用时的编译顺序和变量污染
Sass 控制指令没有“运行时”概念,所有逻辑都在编译阶段展开。这意味着 @if 判断的是变量当前值,@for 和 @each 的迭代次数也是编译期确定的——你没法在循环里动态改 $i 来控制次数,也不能在 @if 里调用 JS 函数去算条件。
变量污染最隐蔽:在 @each 块里用 $item: ... 赋值,这个 $item 会泄漏到外层作用域(Sass 默认行为),后续同名变量会被覆盖。很多人以为块级作用域,其实不是。
- 显式加
!local修饰符可限制作用域:$item: value !local - 嵌套使用时,优先考虑拆成多个 mixin,而不是硬塞进一层
@if包着@each再包@for——可读性和调试成本会陡增 - 所有控制指令都不支持异步、延迟或条件中断,复杂逻辑建议移到构建脚本(如 PostCSS 插件)里做,别强塞进 Sass
真正麻烦的不是语法记不住,而是习惯性当成编程语言来用。Sass 控制指令本质是模板展开工具,不是逻辑引擎——这点一旦模糊,后面全是坑。










