Multiple selectors in loop in LESS

淺唱寂寞╮ 提交于 2019-12-12 15:18:09

问题


I am using the following code to generate a column layout using LESS CSS:

.columnBuilder (@index) when (@index =< @columnCount) {

  .container_@{columnCount} .grid_@{index}  {
    width: unit(((@baseWidth / @columnCount) * @index)-10, px);
  }

  .columnBuilder(@index + 1);
}

Which gives me an output:

.container_24 .grid_1 {
  width: 69px;
}
.container_24 .grid_2 {
  width: 148px;
}
.container_24 .grid_3 {
  width: 227px;
}

etc...

How would i now create a new less function that would give an output of:

.grid_1,
.grid_2,
....,
.grid_N {
  display: inline;
  float: left;
  margin-left: 5px;
  margin-right: 5px;
}

Where N is defined as @columnCount: 24;, though the column count is not set, it can be changed to any number. I am aware i could create a body for each grid_X would like to avoid it to keep clutter down.


回答1:


Using :extend() in LESS 1.4+

This seems to accomplish it more elegantly. You first define the initial values you will want extended in a hard coded .grid_1 class (at present, LESS will not extend dynamically generated classes), then add an extender mixin in your loop to extend to that class. Like so:

.grid_1 { //this acts as the "launch point" for extending them all
    display: inline;
    float: left;
    margin-left: 5px;
    margin-right: 5px;
}

.columnBuilder (@index) when (@index =< @columnCount) {
  //we are going to use this class twice, so just calculate it once
  @gridClass: ~'.grid_@{index}';
  //this is your original code except the variable now used for the grid class
  .container_@{columnCount} @{gridClass} {
    width: unit(((@baseWidth / @columnCount) * @index)-10, px);
  }
  //this is your extender feature, which does not do so for the initial .grid_1
  //which was set above as our launch point.
  @{gridClass} {
    .extender() when (@index > 1) {
      &:extend(.grid_1 all);
    }
    .extender() when (@index = 1) {}
    .extender();
  }
  //iterate the loop just as you were doing
  .columnBuilder(@index + 1);
}
//call the loop starting at 1
.columnBuilder(1);

Output is your expected:

.grid_1,
.grid_2,
....,
.grid_N {
  display: inline;
  float: left;
  margin-left: 5px;
  margin-right: 5px;
}



回答2:


As it turns out, LESS has no native support for something like this and will always create multiple blocks of CSS each with its own body, so you need to run a little hack with mixins. I used the following:

.columnBuilderX (@index) when (@index = 1) {

  @isel: ~".grid_@{index}, ";

  .columnBuilderX (@index + 1, @isel);
}

.columnBuilderX (@index, @innerSel) when (@index =< (@columnCount - 1)) {

  @isel: @innerSel + ~".grid_@{index}, ";

  .columnBuilderX (@index + 1, @isel);
}

.columnBuilderX (@index, @innerSel) when (@index = @columnCount) {
  @isel: @innerSel + ~".grid_@{index} ";

  @{isel} {
    display: inline;
    float: left;
    margin-left: 5px;
    margin-right: 5px;
  }

  .columnBuilderX (@index + 1, @isel);
}

Which produced for me:

.grid_1,  .grid_2,  .grid_3,  .grid_4,  .grid_5,  .grid_6,  .grid_7,  .grid_8,  .grid_9,  .grid_10,  .grid_11,  .grid_12,  .grid_13,  .grid_14,  .grid_15,  .grid_16,  .grid_17,  .grid_18,  .grid_19,  .grid_20,  .grid_21,  .grid_22,  .grid_23,  .grid_24 {
  display: inline;
  float: left;
  margin-left: 5px;
  margin-right: 5px;
}

The first mixin is the initial mixin that is called that does not already have an inner selector, the second mixin requires a second param, which is the variable we create in the first, which then runs recursively until we hit our last column as defined by the when clause, where we add our last selector without the comma, and then use the selector list we have built in to apply our CSS too.

If anybody can come up with something simpler than this, please create an answer.



来源:https://stackoverflow.com/questions/18153688/multiple-selectors-in-loop-in-less

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