在 Less 中增加一个变量

Increase a variable in Less

是否可以在 Less 中增加一个变量?

@i: 0;

.one { border: @i++; }
.two { border: @i++; }
.tree { border: @i++; }

或者以某种方式使用 mixin,比如

.increase() {
    @i: @i+1;
    @increase: @i;
}

为了更好的说明问题:

@icon_width: 32px;

.social{
  background: url('snippet_with_n_images');

  .facebook:   background-position-x: -@icon_width*0;
  .twitter:    background-position-x: -@icon_width*1;
  .googlep:    background-position-x: -@icon_width*2;
  ...
  .pinterest:  background-position-x: -@icon_width*(n-1);
  .linkedin:   background-position-x: -@icon_width*n;

  /*be replaced by */
  .next(): {
     background-position-x: -@icon_width*@i++;
  }
  .facebook:   .next();
  .twitter:    .next();
  .googlep:    .next();
  ...
  .pinterest:  .next();
  .linkedin:   .next();
}

简单来说,在Less中不使用循环(mixin)是不可能增加同一个变量的。这是因为 Less 会延迟加载变量,因此多次递增会导致递归定义错误。以下片段:

@i: 0;
.one { @i: @i + 1; border: @i; }
.two { @i: @i + 1; border: @i; }
.three { @i: @i + 1; border: @i; }

编译时会给出:

NameError: Recursive variable definition for @i on line 4, column 7:

使用问题中的混入 (.increase()) 仍然会导致与上面提供的错误相同的错误。


最好的递增方式是使用混合循环。对于问题中提供的修改示例,循环应如下所示:

@icon_width: 32px;
@social-networks: facebook, twitter, googlep, pinterest, linkedin; /* an array with list of networks */
.social{
  background: url('snippet_with_n_images');
  .loop-social(1); /* call loop with initial value as 1 */
}
.loop-social(@index) when (@index < length(@social-networks)){ /* iterate till index is less than array length */
  @social-network: extract(@social-networks, @index); /* extract value corresponding to index from array */
  .@{social-network}{ /* use extracted social network value as selector */
    background-position-x: -@icon_width*@index; /* assign calculated value, the index would incremented for each iteration */
  }
  .loop-social(@index + 1); /* call next iteration with incremented value */
}

上面的 Less 代码在编译时会产生以下 CSS:

.social {
  background: url('snippet_with_n_images');
}
.social .facebook {
  background-position-x: -32px;
}
.social .twitter {
  background-position-x: -64px;
}
.social .googlep {
  background-position-x: -96px;
}
.social .pinterest {
  background-position-x: -128px;
}