Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create nested loops with LESS CSS?

Tags:

css

less

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?

like image 587
Cristian Avatar asked Jun 09 '13 15:06

Cristian


2 Answers

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);
like image 182
Cristian Avatar answered Sep 30 '22 13:09

Cristian


An Unnested Solution

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.

like image 25
ScottS Avatar answered Sep 30 '22 15:09

ScottS