轻松在mixin中重复选择器声明

时间:2013-01-24 03:27:46

标签: css css-selectors less

我正在尝试为某些表格行声明背景图片图标:

.i(@file:'file.png', @type) {
    &.@{type} {
      td:first-child {
        background-image: url('../img/@{file}');
      }
    }
  }

我希望能够同时传递多种图像类型:

.i('code.png', 'asp, php, rb, py')

并有效地做到这一点:

.i(@file:'file.png', @type) {
  &.@{type1},
  &.@{type2},
  &.@{type3},
  &.@{type4}, {
    td:first-child {
      background-image: url('../img/@{file}');
    }
  }
}

我知道CSS输出会有所不同,最后一个代码示例仅用于说明目的。

关于如何实现这一点的任何想法,只是将一堆空选择器声明为占位符?

1 个答案:

答案 0 :(得分:7)

已更新为LESS 1.5

此代码使用LESS 1.5+中提供的较新extract()length()函数,在LESS的更高版本中更有效地生成相同的效果。输出将与原始示例相同。

.i(@file:'file.png', @types) {

  //find length to make the stop point
  @stopIndex: length(@types);

  //set up our LESS loop (recursive)
  .loopTypes (@index) when (@index =< @stopIndex) {
    @class: extract(@types,@index);
    //print the CSS
    &.@{class} {
        td:first-child {
          background-image: url('../img/@{file}');
        }
      }

        // next iteration
        .loopTypes(@index + 1);
    }

    // "call" the loopingClass the first time getting first item
    .loopTypes (1);
}

.myClass {
  .i('code.png'; asp, php, rb, py;);
}

使用LESS 1.3.3中的循环和内联Javascript

这花了几个小时才提出来(不,我没有一大堆的空闲时间来处理它,我只是无可救药地上瘾......)。花费时间最长的部分之一是弄清楚为什么当我返回数组的@stopIndex并且抛出类型错误时,我的.length没有被LESS视为数字。我终于发现我需要明确告诉它使用LESS的unit()函数将其视为数字。

该解决方案利用了这些来源的一般概念:

  1. LESS looping
  2. Javascript functions in LESS
  3. <强> LESS

    .i(@file:'file.png', @type) {
      //find length to make the stop point
      @stopIndex: unit(`(function(){ return @{type}.split(",").length})()`);
      //need to get the first item in @type
      @firstClass: ~`(function(){ 
          var clsArray = @{type}.replace(/\s+/g, '').split(",");   
          return clsArray[0]; 
        })()`;
    
      //set up our LESS loop (recursive)
      .loopTypes (@index, @captureClass) when (@index < @stopIndex) {
        @nextClass: ~`(function(){ 
          var clsArray = @{type}.replace(/\s+/g, '').split(",");
          //don't let it try to access past array length
          if(@{index} < (@{stopIndex} - 1)) {
           return clsArray[@{index} + 1]; 
          } 
          else { return '' }
        })()`;
    
        //print the CSS
        &.@{captureClass} {
            td:first-child {
              background-image: url('../img/@{file}');
            }
          }
    
            // next iteration
            .loopTypes(@index + 1, @nextClass);
        }
    
        // define guard expressoin to end the loop when past length
        .loopTypes (@stopIndex, @captureClass) {}
    
        // "call" the loopingClass the first time getting first item
      .loopTypes (0, @firstClass);
    }
    
    .myClass {
      .i('code.png', 'asp, php, rb, py');
    }
    

    CSS输出

    .myClass.asp td:first-child {
      background-image: url('../img/code.png');
    }
    .myClass.php td:first-child {
      background-image: url('../img/code.png');
    }
    .myClass.rb td:first-child {
      background-image: url('../img/code.png');
    }
    .myClass.py td:first-child {
      background-image: url('../img/code.png');
    }