Skip to content

Less - 循环

Less 不提供许多编程语言中传统的 for 或 while 循环结构。相反,Less 通过强大地结合三种特性来实现迭代或循环行为:递归 mixin(调用自身的 mixin)、守卫表达式(Guard Expressions,即条件 when 子句),以及有时是模式匹配(Pattern Matching,根据特定的参数值或模式定义执行的 mixin)。这种技术允许你在编译过程中编程方式生成重复的 CSS 模式。

核心思想是创建一个应用一些样式,然后使用修改后的参数调用自身的 mixin,直到守卫条件(guard condition)停止递归。

让我们演示如何创建一个生成多个 width 属性的循环。尽管由于 CSS 层叠规则,浏览器只会应用最后一个有效的 width 属性,但本示例清晰地展示了循环机制。

考虑以下 HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css" type="text/css" />
<title>LESS Loops Example</title>
</head>
<body>
<div class="iterative-box">This box will have widths generated by a loop.</div>
</body>
</html>

接下来,创建包含递归 mixin 的 style.less 文件:

// 用于生成 width 属性的递归 mixin
// @current-iteration: 当前迭代次数(用作计数器)
// @max-iterations: 所需的总迭代次数(用于守卫)
.generate-widths(@current-iteration) when (@current-iteration > 0) { // 守卫:只要 @current-iteration 大于 0,循环就继续
// 递归调用:使用递减的计数器调用 mixin
// 这个调用先发生,因此属性按照 @current-iteration 值升序输出。
.generate-widths((@current-iteration - 1));
// 本次迭代中生成的 CSS 属性
// 我们乘以 50px 进行演示
width: (@current-iteration * 50px);
}
.iterative-box {
height: 100px; // 固定高度,以便可见
background-color: lightblue;
border: 1px solid blue;
// 启动循环,例如迭代 3 次
.generate-widths(3); // 这将生成 width: 50px, width: 100px, width: 150px
}

要将 style.less 编译成 style.css,使用以下命令:

lessc style.less style.css

执行此命令将创建包含以下内容的 style.css 文件:

.iterative-box {
height: 100px;
background-color: lightblue;
border: 1px solid blue;
/* 来自 .generate-widths(1) 的输出 */
width: 50px;
/* 来自 .generate-widths(2) 的输出 */
width: 100px;
/* 来自 .generate-widths(3) 的输出 */
width: 150px;
}

当你在浏览器中打开 index.html 时:

  • .iterative-box div 将应用淡蓝色背景和蓝色边框样式。
  • Less 编译器通过递归的 .generate-widths mixin 生成了三个 width 声明:width: 50px;、width: 100px; 和 width: 150px;。
  • 由于 CSS 层叠规则(同一属性在同一特异性(specificity)下,后面的声明会覆盖前面的声明),浏览器会应用最后一个 width 声明,所以盒子的有效宽度将是 150px。
  • 递归的工作原理如下:.generate-widths(3) 调用 .generate-widths(2),后者调用 .generate-widths(1)。.generate-widths(1) 输出 width: 50px;。然后 .generate-widths(2) 输出 width: 100px;。最后,.generate-widths(3) 输出 width: 150px;。守卫 when (@current-iteration > 0) 在 @current-iteration 变为 0 时停止递归。

虽然上面的示例生成了同一属性的多个实例,但 Less 循环更常用于:

  • **生成工具类:**创建像 .margin-top-10、.margin-top-20 等一系列类。
  • **创建网格系统:**为一个响应式网格生成列类(例如,.col-1、.col-2、… .col-12)。
  • **复杂的调色板或主题:**遍历颜色列表以生成主题样式。
  • **基于步骤的动画:**生成关键帧或动画步骤。

Less 循环,通过递归 mixin 和守卫实现,是该预处理器强大能力的证明,使开发者能够编写更简洁和程序化的样式表。