How to generate CSS with loop in less
Update, 3/28/2022:
Requires Less v3.9.0
each(range(1%, 100%, 1), {
.span-@{index} {
width: @value;
}
});
Output
.span-1 {
width: 1%;
}
.span-2 {
width: 2%;
}
.span-3 {
width: 3%;
}
.
.
.
.span-98 {
width: 98%;
}
.span-99 {
width: 99%;
}
.span-100 {
width: 100%;
}
Quoting the docs:
Creating a
for
loop usingrange
andeach
Requires Less v3.9.0
You can emulate a
for
loop simply by generating a numerical list and usingeach
to expand it to a ruleset.
Notes:
range(1%, 100%, 1)
: makes a list starting from 1% to 100%, with step value of 1, that is:1% 2% 3% ... 100%
each(list, rules)
: Bind the evaluation of a ruleset to each member of a list.@value
: each value in the list, i.e.1%
,2%
, ...@index
: index of each value, starting from 1 (numerical position, 1-based)
Original Answer:
Try this:
@iterations: 5;
.span-loop (@i) when (@i > 0) {
.span-@{i} {
width: ~"@{i}%";
}
.span-loop(@i - 1);
}
.span-loop (@iterations);
Output:
.span-5 {
width: 5%;
}
.span-4 {
width: 4%;
}
.span-3 {
width: 3%;
}
.span-2 {
width: 2%;
}
.span-1 {
width: 1%;
}
You can try it out on less2css.
Update, 4/3/2014
Here is a more flexible version with more options:
.custom-loop( @base-value:@n ; @n ; @unit : px; @j : 1 ;@_s:0 ; @step-size:1 ; @selector:~".span-"; @property : width)
when not(@n=0) {
@size : @base-value+@_s;
@{selector}@{j}{
@{property} : ~"@{size}@{unit}";
}
.custom-loop(@base-value , (@n - 1), @unit , (@j + 1) , (@_s+@step-size) , @step-size, @selector, @property);
}
You can call this by only @n
which is the required argument:
.custom-loop(@n:3);
Which will output:
.span-1 {
width: 3px;
}
.span-2 {
width: 4px;
}
.span-3 {
width: 5px;
}
But if you want to have control over each parameter, here is an example using all custom parameters:
.custom-loop( @n: 3 , @base-value:1, @unit: '%', @property:font-size, @selector: ~".fs-", @step-size: 2);
This will output:
.fs-1 {
font-size: 1%;
}
.fs-2 {
font-size: 3%;
}
.fs-3 {
font-size: 5%;
}
Parameter descriptions
@n : integer, The number of iterations.
@base-value (optional): integer, The starting value for the loop to be assigned to the property. Default value is the same is the value assigned for the number of iterations
@n
.@unit (optional): string, The unit for the property. Default value is
px
.@property (optional): non-string or string The CSS property. Default value is
width
@selector (optional): escaped string, The selector used for the loop. Could be anything as long as it is passed in as a escaped string.
@step-size (optional): integer, The value by which the loop increments by.
NOTES
Note 1: The custom selector is passed in as a escaped string. If it is not escaped, it is not going to work as expected.
Note 2: The mixin is called by explicitly using the parameter name. This has some advantages and disadvantages:
Note 3: The unit is passed in as a string.
Advantages
- It is clear what parameter is called
- You don't have to rely on the order of parameters and remember which parameter comes first, second, …
Disadvantages
- I guess it looks a bit ugly ?
- (add to the list and/or change the implementation if you know a better one)
Please note, that since version 3.7 Less has an each() function, which can be easily used with the range()
function to produce the wanted code - like this:
each(range(100),{
.span@{value} { width: @value * 1%; }
});
All, I found a way to output css in loop. pleae review it .thanks.
@iterations: 100;
// helper class, will never show up in resulting css
// will be called as long the index is above 0
.loopingClass (@index) when (@index > 0) {
// create the actual css selector, example will result in
// .myclass_30, .myclass_28, .... , .myclass_1
(~".span@{index}") {
// your resulting css
width: percentage((@index - 1) *0.01);
}
// next iteration
.loopingClass(@index - 1);
}
// end the loop when index is 0
.loopingClass (0) {}
// "call" the loopingClass the first time with highest value
.loopingClass (@iterations);
It is impossible to do within given methods.
But possible like this:
.loopingClass (@index) when (@index > 0){
.span_@{index}{
width: @index px;
}
.loopingClass(@index - 1);
}
.loopingClass(5);
Resilt will be like this:
.span_100 {
width: 100 px;
}
.span_99 {
width: 99 px;
}
.span_98 {
width: 98 px;
}
.span_97 {
width: 97 px;
}
.span_96 {
width: 96 px;
}
.span_95 {
width: 95 px;
}
and e.t.c.