CSS预处理器Sass中的控制命令_@if、@for与@each的用法

2次阅读

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

CSS预处理器Sass中的控制命令_@if、@for与@each的用法

@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 控制指令本质是模板展开工具,不是逻辑引擎——这点一旦模糊,后面全是坑。

text=ZqhQzanResources