50

I am not familiar with Less. In my understanding, I think Less can transform the less format file to standard css file(if I am wrong, please correct me). Now I have a question below.

Say you would generate 100 CSS classes like below(from .span1 to .span100) in a single CSS file. I want to know whether less can generate a CSS file like it?

...
.span5 {
  width: 5%;
}

.span4 {
  width: 4%;
}

.span3 {
  width: 3%;
}

.span2 {
  width: 2%;
}

.span1 {
  width: 1%;
}
1
  • 8
    This is a perfectly legitimate question and is exactly the one I had. Please re-open this. Commented Nov 17, 2013 at 5:32

4 Answers 4

71

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 using range and each

Requires Less v3.9.0

You can emulate a for loop simply by generating a numerical list and using each 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

  1. @n : integer, The number of iterations.

  2. @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.

  3. @unit (optional): string, The unit for the property. Default value is px.

  4. @property (optional): non-string or string The CSS property. Default value is width

  5. @selector (optional): escaped string, The selector used for the loop. Could be anything as long as it is passed in as a escaped string.

  6. @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

  1. It is clear what parameter is called
  2. You don't have to rely on the order of parameters and remember which parameter comes first, second, …

Disadvantages

  1. I guess it looks a bit ugly ?
  2. (add to the list and/or change the implementation if you know a better one)
Sign up to request clarification or add additional context in comments.

3 Comments

Only this syntax works with less.php (leafo), thanks !
One small critique. I prefer @j:@base-value and (@j+@step-size) so that I get meaningful class names instead of an index without context. In your solution, the class name is not matching the value that's set in the property when base-value != step-size != 1.
you are god bro
23

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);

4 Comments

Please refer to the Less source code of Bootstrap (namely mixins.less). Search for ".spanX" string, I hope that it's next to what you mean to get at.
You use guard along with a recursive mixin as did the authors of Bootstrap.
Please head to this post: Do a loop with LESS css.
@Joe.wang code was not working in less2css.org. So, I played and got this:` @iterations: 100; .loopingClass (@index) when (@index > 0) { .span@{index} { width: percentage((@index ) *0.01); } .loopingClass(@index - 5); } .loopingClass (0) {} .loopingClass (@iterations);` @iterations: 100; .loopingClass (@index) when (@index > 0) { .span@{index} { width: percentage((@index ) *0.01); } .loopingClass(@index - 5); } .loopingClass (0) {} .loopingClass (@iterations); `
13

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%; }
});

Comments

1

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.

2 Comments

Please add answer with code or fiddle. picture on code is consider bad answer
Isn't this answer a duplicate of @Amin answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.