在LESS CSS中动态定义变量

时间:2013-08-04 02:01:24

标签: css less interpolation mixins

我正在尝试通过实际为它们分配一个复合名称来创建一个动态定义LESS CSS变量的mixin。

简化用例(不是真实用例):

.define(@var){
    @foo{var}: 0;
}

然后人们可以这样调用mixin:

.define('Bar'){
    @fooBar: 0;
}

由于在使用选择器名称时可以进行这种字符串插值,我想知道变量名是否可行;到目前为止,我对我尝试过的各种语法没有运气(除了上述内容,我尝试了转义,引用,使用~前缀等)。

修改

我只是尝试了一件事,我觉得我可能会接近;但我遇到了LESS语法的奇怪之处。如果我写这个:

.define(@var){
    #namespace {
         @foo: @var;
    }
}

然后这样称呼它:

.define(0)

然后我可以在通常的命名空间方式中使用@foo

.test {
     #namespace;
     property: @foo; /* returns 0 */
}

但是,在字符串插值选择器的情况下,同样的情况不适用:

.define(@var, @ns){
    #@{ns} {
         @foo: @var;
    }
}

.define(0, namespace);

.test {
     #namespace;
     property: @foo;
}

上面的代码给出了以下错误:

  

名称错误:#namespace未定义

然而,字符串插值是成功且有效的。事实上,如果我拿走.test部分并修改上面的内容来输出测试属性,我可以看到CSS被正确解析了。我的意思是:

.define(@var, @ns){
    #@{ns} {
         @foo: @var;
         prop: @foo;
    }
}

.define(0, namespace);

输出以下CSS:

#namespace {
    prop: 0;
}

4 个答案:

答案 0 :(得分:12)

这无法完成

目前,LESS目前无法做到。如果您事先知道要允许使用的变量名称 (换句话说,不是完全动态的),我可以想到两个可能的“变通方法” 。然后就可以完成下列其中一项:

想法#1(变量变量)

.define(@var) {
  @fooBar: 0;
  @fooTwo: 2;
  @fooYep: 4;

  @fooSet: 'foo@{var}';
}

.define(Two);
.test {
  .define(Bar);
  prop: @@fooSet;
}
.test2 {
  prop: @@fooSet;
}

想法#2(参数混合)

<强> LESS

.define(@var) {
  .foo() when (@var = Bar) {
    @fooBar: 0;
  }
 .foo() when (@var = Two) {
    @fooTwo: 2;
  }
 .foo() when (@var = Yep) {
    @fooYep: 4;
  }
  .foo();
}

.define(Two);
.test {
  .define(Bar);
  prop: @fooBar;
}
.test2 {
  prop: @fooTwo;
}

CSS输出(两种想法)

.test {
  prop: 0;
}
.test2 {
  prop: 2;
}

结论

但是我不确定它是多么有用,我也不知道它是否可以在你的实际用例中有任何实际的应用程序(因为你提到上面的内容并不是真正的用例)。如果你想在LESS中使用一个完全动态的变量,那么它就不能通过LESS本身完成。

答案 1 :(得分:2)

我不确定你想要用什么,但我的一个建议是基于@ScottS答案。在我的现实世界中,我需要创建一个网络应用程序,它会显示几个品牌,每个品牌都有自己的文字颜色,背景等...所以我开始追逐一种方法来实现这一点,我是什么很容易在SASS上做,结果如下:

LESS

// Code from Seven Phase Max
// ............................................................
// .for
.for(@i, @n) {.-each(@i)}
.for(@n)     when (isnumber(@n)) {.for(1, @n)}
.for(@i, @n) when not (@i = @n)  {
    .for((@i + (@n - @i) / abs(@n - @i)), @n);
}

// ............................................................
// .for-each

.for(@array)   when (default()) {.for-impl_(length(@array))}
.for-impl_(@i) when (@i > 1)    {.for-impl_((@i - 1))}
.for-impl_(@i)                  {.-each(extract(@array, @i))}


// Brands
@dodge : "dodge";
@ford : "ford";
@chev : "chev";

// Colors
@dodge-color : "#fff";
@ford-color : "#000";
@chev-color : "#ff0";

// Setting variables and escaping than
@brands: ~"dodge" ~"ford" ~"chev";

// Define our variable   
.define(@var) {
  @brand-color: '@{var}-color';
}

// Starting the mixin
.color() {
    // Generating the loop to each brand
    .for(@brands); .-each(@name) {
        // After loop happens, it checks what brand is being called
        .define(@name);
         // When the brand is found, match the selector and color
        .brand-@{name} & {
            color: @@brand-color;
        }
    }
}

.carColor {
    .color();
}

结果将是:

CSS

.brand-dodge .carColor {
    color: "#fff";
}
.brand-ford .carColor {
    color: "#000";
}
.brand-chev .carColor {
    color: "#ff0";
}

这非常棘手,我不得不使用几个元素来获得我需要的东西,首先使用Seven Phase Max提供的一组mixins,你可以找到它here而且@ScottS答案是从我的谜题中遗漏的那块...希望这可以帮助你和其他需要创建一组变量的人成为另一个变量的一部分并创建一个更动态更少的文件。

您可以复制我的整个代码并在http://lesstester.com/

进行测试

答案 2 :(得分:1)

要跟进接受的答案,您还可以通过扩展.define()mixin来定义变量的值,如下所示。这允许您在规则中使用一组临时变量。

.define(@var, @val) {
  .foo() when (@var = temp1) {
    @temp1: @val;
  }
 .foo() when (@var = temp2) {
    @temp2: @val;
  }
 .foo() when (@var = temp3) {
    @temp3: @val;
  }
  .foo();
}

.define(temp2, 2);
.test {
  .define(temp1, 0);
  prop: @temp1;
}
.test2 {
  prop: @temp2;
}

CSS输出

.test {
  prop: 0;
}
.test2 {
  prop: 2;
}

以下是mixin中更复杂的gist of how I use this,用于生成背景大小的响应式背景图片:cover; (以及IE8后备)。

答案 3 :(得分:1)

我没有时间构建示例,但上述内容都不像定义变量那样快速简单,然后基于它组装导入。然后只有多个文档,其中定义了相同的变量。

@whitelabel: 'foo';
@import 'whitelabel/@{whitelabel}/colors';