Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Lists and loops

Less has no @for and @each like Sass. Repetition is done in two ways: with a recursive mixin that calls itself, and with the each() function. Loops are needed to get dozens of utility classes from one list of values.

Lists

A list is values separated by commas or spaces in one variable. There are functions for working with it (the examples use @list: 4px, 8px, 16px):

FunctionWhat it returnsExampleResult
length()The number of itemslength(@list)3
extract()An item by its number, counting from 1extract(@list, 2)8px
range()A list of numbersrange(4)1 2 3 4
// styles/main.less
@sizes: 12px, 16px, 20px;
 
.text-small {
  font-size: extract(@sizes, 1);
}
 
.text-large {
  font-size: extract(@sizes, length(@sizes));
}
.text-small {
  font-size: 12px;
}
.text-large {
  font-size: 20px;
}

A recursive mixin

A mixin with a guard calls itself with a smaller number while the condition is true. This is how grid columns are created:

// styles/main.less
.make-columns(@i) when (@i > 0) {
  .col-@{i} {
    width: percentage((@i / 4));
  }
  .make-columns(@i - 1);
}
 
.make-columns(4);
.col-4 {
  width: 100%;
}
.col-3 {
  width: 75%;
}
.col-2 {
  width: 50%;
}
.col-1 {
  width: 25%;
}

The call .make-columns(4) output .col-4, then called .make-columns(3) and so on down to zero, where the condition @i > 0 is false and the recursion stopped.

The each function

each() is simpler: it walks through a list and runs a ruleset for every item. Inside you have @value — the value, @key — the key, and @index — the number from 1:

// styles/main.less
@spacers: 4px, 8px, 16px;
 
each(@spacers, {
  .mt-@{index} {
    margin-top: @value;
  }
});
.mt-1 {
  margin-top: 4px;
}
.mt-2 {
  margin-top: 8px;
}
.mt-3 {
  margin-top: 16px;
}

Looping over a map

With a map each() gives you the key and the value — handy for colour classes:

// styles/main.less
@colors: {
  primary: #2563eb;
  success: #16a34a;
  danger: #dc2626;
}
 
each(@colors, {
  .text-@{key} {
    color: @value;
  }
});
.text-primary {
  color: #2563eb;
}
.text-success {
  color: #16a34a;
}
.text-danger {
  color: #dc2626;
}
<style>
  .text-primary {
    color: #2563eb;
  }
  .text-success {
    color: #16a34a;
  }
  .text-danger {
    color: #dc2626;
  }
</style>
 
<p class="text-primary">A new post</p>
<p class="text-success">The post is published</p>
<p class="text-danger">Saving failed</p>

Common mistake

A recursive mixin without a guard or without decreasing the counter never stops:

// styles/main.less
.make-columns(@i) {
  .col-@{i} {
    width: percentage((@i / 4));
  }
  .make-columns(@i - 1);
}
 
.make-columns(4);

Less goes into endless recursion, and compilation fails with the unclear error SyntaxError: undefined on the line of the call. Always write when (@i > 0) and call the mixin with @i - 1.

Thanks for reading!

Donate to the site — we work hard for you.