How do I create nested loops with LESS CSS?

拥有回忆 提交于 2019-12-05 07:19:26

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

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.

Old question but maybe it's worth mentioning that Less can now do this easier

Function

.for(@i, @n, @r){@r();._(@i)}
.for(@n, @r)when(isnumber(@n)){.for(0, @n, @r)}
.for(@i, @n, @r)when not(@i = @n - 1){.for((@i + ((@n - @i) / abs(@n - @i))), @n, @r)}

Usage

.for(3, {._(@i) {
  .for(3, {._(@j) {
    item-@{i}-@{j} {
      i: @i;
      j: @j;
    }
  }});
}});

Example: Codepen

.loop(@n: 1, @m: @n, @k: @n * @m) when(@k > 0) {
    .loop(@n, @m, @k - 1);

    @i: `Math.floor((@{k} - 1) / @{m})`;
    @j: @k - @i * @n - 1;

    /*
        @i runs up 1 to @n,
        @j runs up 1 to @m and
        @k runs up 1 to @n * @m

        for example:
    */

    &:nth-child(@{k}) {
        top: 50px * @i;
        left: 100px * @j;
    }
}

/* using: */
.loop(3,4);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!