在较少的CSS中动态定义变量

在较少的CSS中动态定义变量,css,less,interpolation,mixins,Css,Less,Interpolation,Mixins,我试图创建一个mixin,通过实际为变量分配一个复合名称,在较少的CSS中动态定义变量 简化用例(不是真实用例): 那么我们可以这样称呼mixin: .define('Bar'){ @fooBar: 0; } 由于这种字符串插值在使用选择器名称时是可能的,我想知道对于变量名称是否也可能这样;到目前为止,我对我尝试的各种语法都没有什么好运气(除了上面提到的,我尝试了转义、引用、使用~前缀等等) 编辑 我又试了一件事,我觉得我可能很接近;但我正经历着一种奇怪的更少的语法。如果我这样写: .

我试图创建一个mixin,通过实际为变量分配一个复合名称,在较少的CSS中动态定义变量

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

那么我们可以这样称呼mixin:

.define('Bar'){
    @fooBar: 0;
}
由于这种字符串插值在使用选择器名称时是可能的,我想知道对于变量名称是否也可能这样;到目前为止,我对我尝试的各种语法都没有什么好运气(除了上面提到的,我尝试了转义、引用、使用
~
前缀等等)

编辑 我又试了一件事,我觉得我可能很接近;但我正经历着一种奇怪的更少的语法。如果我这样写:

.define(@var){
    #namespace {
         @foo: @var;
    }
}
然后这样称呼它:

.define(0)
然后,我可以按照通常的名称空间方式使用
@foo

但是,这一点不适用于字符串插值选择器:

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

.define(0, namespace);

.test {
     #namespace;
     property: @foo;
}
上面的代码给出了以下错误:

名称错误:#命名空间未定义

但是,字符串插值是成功和有效的。事实上,如果我去掉
.test
部分并修改上面的内容以输出一个test属性,我可以看到CSS被正确解析。我的意思是:

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

.define(0, namespace);
输出以下CSS:

#namespace {
    prop: 0;
}
这是不可能做到的 你想做的事在短时间内是不可能的。如果您提前知道希望允许使用哪些变量名,我可以想出两种可能的“变通方法”(换句话说,不是完全动态的)。然后可以执行以下操作之一:

想法#1(可变变量) Idea#2(参数混合) 更少

.define(@var){
.foo()时(@var=Bar){
@fooBar:0;
}
.foo()时(@var=Two){
@fooTwo:2;
}
.foo()时(@var=yesp){
@fooYep:4;
}
.foo();
}
.界定(二);
.测试{
.定义(酒吧);
道具:@fooBar;
}
.test2{
道具:@fooTwo;
}
CSS输出(用于两种想法)
.test{
道具:0;
}
.test2{
提案:2;
}
结论
但我不确定这两种方法到底有多有用,也不知道它是否能在您的实际用例中有任何实际应用(因为您提到的上述不是真正的用例)。如果你想在LESS中使用一个完全动态的变量,那么它不能通过LESS本身来实现。

我不确定你想用什么,但我的一个建议是基于@ScottS-answer。在我的现实世界中,我需要创建一个web应用程序,它将显示几个品牌,每个品牌都有自己的文本颜色、背景等等。。。因此,我开始寻找一种方法,用更少的时间完成这项工作,我可以在SASS上轻松完成,结果如下:

较少的 结果将是:

CSS 这是非常棘手的,我不得不使用几个元素来获得我需要的,首先使用了Seven Phase Max提供的一组混合器,你可以找到它,然后,@ScottS的答案就是我的拼图中缺少的部分。。。希望这能帮助您和其他需要创建一组变量作为另一个变量的一部分,并创建一个更动态的文件的人


您可以复制我的整个代码并在

处进行测试,以跟进已接受的答案。您还可以通过扩展.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输出
在mixin中,有一个更复杂的方法用于生成具有背景大小的响应性背景图像:cover;(还有一个IE8回退)。

我没有时间构建这些示例,但是上面的任何一个都不如定义一个变量然后根据它组装导入那样快速和简单。然后只需要定义相同变量的多个文档

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

非常感谢你的回答;不幸的是,你的两个想法都不能帮助我解决现实世界中的问题,尽管使用参数混合会减少我的一些代码。不过,我尝试了另一种解决方案,您可以检查编辑:对此有何想法?您使用名称空间思想进行的编辑受到以下事实的影响:目前。名称空间基本上是一个混合体。@Sunyatasattva:我也不知道名称空间给你带来了什么好处,你可以简单地调用
.define(0)
在任何代码块中,您都可以将
#名称空间
放入其中。两者都允许您在该点使用
@foo
变量。您可能需要进一步描述您实际上正在尝试做什么以及为什么要这样做。感谢您提供了该问题的链接。事实上,您是对的,使用名称空间只会为我节省一点代码;在开始尝试这种方法时,我希望可以调用
prop:#namespace>@fooBar
,但事实并非如此。谢谢你的帮助。非常好的回答。。。我需要一点时间来思考这个问题,但这是值得的!谢谢你的评论。我会看看你的代码。我的问题已经问了将近一年了,我记不清自己到底想达到什么目标(我一定是以另一种方式实现的)。我会研究一下你发布的内容,同时也会挖掘我的旧代码,看看它是否合适。以防万一,我唯一的问题是,你真的需要这些变量吗?(这些变量使这一切变得如此复杂)。就我个人而言,我看不出有任何必要在那里使用
@dodge color
之类的东西(即在一个地方写
dodge
,只是为了让自己不得不在其他地方写
dodge
)。对我来说,这类问题似乎可以通过类似或(+这些方法的任何适当组合)的方式完美解决。@seven Phase max我理解你的观点,但有些情况下我们确实需要生成动态类。。。我的例子非常简单,在这种情况下没有真正意义,但在我的现实世界中,变量是需要的,因为我们只需要设置变量,其余的就让LESS来做。另外需要注意的是,在我们的案例中,CMS将品牌类别设置为body标签,并且每个页面都会
.define(@var) {
  @fooBar: 0;
  @fooTwo: 2;
  @fooYep: 4;

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

.define(Two);
.test {
  .define(Bar);
  prop: @@fooSet;
}
.test2 {
  prop: @@fooSet;
}
// 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();
}
.brand-dodge .carColor {
    color: "#fff";
}
.brand-ford .carColor {
    color: "#000";
}
.brand-chev .carColor {
    color: "#ff0";
}
.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;
}
.test {
  prop: 0;
}
.test2 {
  prop: 2;
}
@whitelabel: 'foo';
@import 'whitelabel/@{whitelabel}/colors';