What I know is that this:
@iterations: 8;
.mixin-loop (@index) when (@index > 0) {
.my-class-@{index} {
width: (100% / @index);
}
.mixin-loop(@index - 1);
}
.mixin-loop (0) {}
.mixin-loop(@iterations);
… Will result in this:
.my-class-8{width:12.5%}
.my-class-7{width:14.285714285714286%}
.my-class-6{width:16.666666666666668%}
.my-class-5{width:20%}
.my-class-4{width:25%}
.my-class-3{width:33.333333333333336%}
.my-class-2{width:50%}
.my-class-1{width:100%}
… Making it the LESS equivalent of:
for (var i = 8; i > 0; -- i) {
// …
}
My question is: What would the LESS equivalent of:
for (var i = 8; i > 0; -- i) {
for (var j = 4; j > 0; -- j) {
// …
}
}
… Look like?
Hm, nevermind—Found it myself.
I’m leaving the answer here for posterity’s sake:
@maxi: 8;
.i-loop (@i) when (@i > 0) {
@maxj: 8;
.j-loop (@j) when (@j > 0) {
.my-class-@{i}-@{j} {
width: (100% / @i);
height: (100% / @j);
}
.j-loop(@j - 1);
}
.j-loop (0) {}
.j-loop(@maxj);
.i-loop(@i - 1);
}
.i-loop (0) {}
.i-loop(@maxi);
I'm only offering this as an alternative here for final output code purposes. My answer does not really address nesting of loops directly (as your question is and your own answer found that solution). Rather, it challenges whether nesting is even best to solve the problem you faced.
Assuming a class structure just as you have (say my-class-2-6
for example), you can reduce from 64 output CSS selectors to just 16 by not nesting them and instead using CSS3 attribute selectors (which may not be desirable, depending on target browsers you need to support). Thus this LESS:
@maxi: 8;
@maxj: 8;
@iSelStart: ~'[class^=my-class-';
@jSelStart: ~'[class$=-';
@ijSelEnd: ~']';
.i-loop (@i) when (@i > 0) {
@{iSelStart}@{i}@{ijSelEnd} {
width: (100% / @i);
}
.i-loop(@i - 1);
}
.j-loop (@j) when (@j > 0) {
@{jSelStart}@{j}@{ijSelEnd} {
height: (100% / @j);
}
.j-loop(@j - 1);
}
//stop loops
.i-loop (0) {}
.j-loop (0) {}
//itialize loops
.j-loop(@maxj);
.i-loop(@maxi);
Becomes this CSS:
[class$=-8] {
height: 12.5%;
}
[class$=-7] {
height: 14.285714285714286%;
}
[class$=-6] {
height: 16.666666666666668%;
}
[class$=-5] {
height: 20%;
}
[class$=-4] {
height: 25%;
}
[class$=-3] {
height: 33.333333333333336%;
}
[class$=-2] {
height: 50%;
}
[class$=-1] {
height: 100%;
}
[class^=my-class-8] {
width: 12.5%;
}
[class^=my-class-7] {
width: 14.285714285714286%;
}
[class^=my-class-6] {
width: 16.666666666666668%;
}
[class^=my-class-5] {
width: 20%;
}
[class^=my-class-4] {
width: 25%;
}
[class^=my-class-3] {
width: 33.333333333333336%;
}
[class^=my-class-2] {
width: 50%;
}
[class^=my-class-1] {
width: 100%;
}
So the example of my-class-2-6
would target the start of the class name my-class-2
giving a width: 50%
and target the end of the class name -6
which would give a height: 16.666666666666668%;
.
Just a thought for any future users facing a similar situation who are only worried about targeting CSS3 browsers.
Update: Added Protection to not Incorrectly Target
As an after thought, it occurred to me that if you have various types of classes that may have an ending of -1
or -2
etc., then your ending CSS may need to have an additional set of code to help filter for just that class. So the j
loop code above would need to have a change to the selector string like so:
@{iSelStart}@{ijSelEnd}@{jSelStart}@{j}@{ijSelEnd} { /*properties*/}
Which would then output this format of code:
[class^=my-class-][class$=-1] {
/*properties*/
}
This way it is looking specifically for the my-class-
"class" that ends in -1
, and would ignore selecting another class like another-class-1
as the original code above would still select. Whether this is an issue or not would purely be related to the design and class naming used in one's site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With