Skip to content

Less - Loops

Less does not feature traditional loop constructs like for or while found in many programming languages. Instead, Less achieves iterative or looping behavior through a powerful combination of three features: recursive mixins (mixins that call themselves), Guard Expressions (conditional when clauses), and sometimes Pattern Matching (defining mixins that execute based on specific argument values or patterns). This technique allows you to programmatically generate repetitive CSS patterns during the compilation process.

The core idea is to create a mixin that applies some styles and then calls itself with modified parameters, until a guard condition stops the recursion.

Example: Generating Multiple Width Properties

Section titled “Example: Generating Multiple Width Properties”

Let’s demonstrate how to create a loop that generates several width properties. While a browser will only apply the last valid width property for a selector due to CSS cascade rules, this example clearly shows the looping mechanism.

Consider the following 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>

Next, create the style.less file with a recursive mixin:

// Recursive mixin to generate width properties
// @iterations: The current iteration count (acts as a counter)
// @max-iterations: The total number of iterations desired (used in the guard)
.generate-widths(@current-iteration) when (@current-iteration > 0) { // Guard: loop continues as long as @current-iteration is greater than 0
// Recursive call: call the mixin with a decremented counter
// This call happens first, so properties are output in ascending order of @current-iteration values.
.generate-widths((@current-iteration - 1));
// CSS property generated in this iteration
// We multiply by 50px for demonstration
width: (@current-iteration * 50px);
}
.iterative-box {
height: 100px; // Fixed height for visibility
background-color: lightblue;
border: 1px solid blue;
// Initiate the loop, e.g., for 3 iterations
.generate-widths(3); // This will generate width: 50px, width: 100px, width: 150px
}

To compile style.less to style.css, use the command:

lessc style.less style.css

Executing this command will create the style.css file with the following content:

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

When you open index.html in a browser:

  • The .iterative-box div will be styled with a light blue background and a blue border.
  • The Less compiler, through the recursive .generate-widths mixin, has produced three width declarations: width: 50px;, width: 100px;, and width: 150px;.
  • Due to CSS cascade rules (where later declarations for the same property override earlier ones within the same specificity), the browser will apply the last width declaration, so the effective width of the box will be 150px.
  • The recursion works as follows: .generate-widths(3) calls .generate-widths(2), which calls .generate-widths(1). .generate-widths(1) outputs width: 50px;. Then .generate-widths(2) outputs width: 100px;. Finally, .generate-widths(3) outputs width: 150px;. The guard when (@current-iteration > 0) stops the recursion when @current-iteration becomes 0.

While the above example generates multiple instances of the same property, Less loops are more commonly used for:

  • Generating Utility Classes: Creating sets of classes like .margin-top-10, .margin-top-20, etc.
  • Creating Grid Systems: Generating column classes for a responsive grid (e.g., .col-1, .col-2, … .col-12).
  • Complex Color Palettes or Themes: Iterating through lists of colors to generate themed styles.
  • Step-based Animations: Generating keyframes or animation steps.

Less loops, achieved through recursive mixins and guards, are a testament to the preprocessor’s power, enabling developers to write more concise and programmatic stylesheets.