12

我正在尝试通过实际为它们分配一个复合名称来创建一个在 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

4 回答 4

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(参数混合)

较少的

.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 本身来完成。

于 2013-08-04T02:43:52.650 回答
2

我不太确定你想用什么,但我的建议之一是基于@ScottS 的回答。在我的现实世界中,我需要创建一个网络应用程序,它会显示几个品牌,每个品牌都有自己的文字颜色、背景等......所以我开始在 LESS 中寻找一种方法来完成这个,我可以在 SASS 上轻松完成,结果如下:

较少的

// 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 提供的 mixin,你可以在这里找到它,然后,@ScottS 的答案是我的谜题中缺少的部分...希望这可以帮助您和其他需要创建一组变量以成为另一个变量的一部分并创建更具动态性的更少文件的人。

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

于 2014-05-22T20:11:03.200 回答
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 中使用它来生成具有背景大小的响应式背景图像:(和 IE8 后备)。

于 2014-10-09T11:07:02.983 回答
1

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

@whitelabel: 'foo';
@import 'whitelabel/@{whitelabel}/colors';
于 2015-09-03T16:48:59.607 回答