使用LESS CSS可以在变量中存储多个参数吗?

时间:2014-03-14 04:30:14

标签: less

我希望以下mixin能够理解我想传递多个参数而不是使用3px, 0, 0, 3px作为单个参数。

注意:我确实知道我可以@myRadius: 3px.border-radius( @myRadius, 0, 0 @myRadius );。我只是不想。

示例代码(粘贴到LESSTESTER以查看输出):

.border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
     -webkit-border-top-right-radius: @topright;
  -webkit-border-bottom-right-radius: @bottomright;
   -webkit-border-bottom-left-radius: @bottomleft;
      -webkit-border-top-left-radius: @topleft;

     -moz-border-radius-topright: @topright;
  -moz-border-radius-bottomright: @bottomright;
   -moz-border-radius-bottomleft: @bottomleft;
      -moz-border-radius-topleft: @topleft;

     border-top-right-radius: @topright;
  border-bottom-right-radius: @bottomright;
   border-bottom-left-radius: @bottomleft;
      border-top-left-radius: @topleft;
}

@myRadius: 3px, 0, 0, 3px;

div {
    .border-radius( @myRadius );
}

2 个答案:

答案 0 :(得分:3)

简而言之:不,目前这是不可能的(变量总是作为一个mixin参数)。 (“参数扩展列表”功能实际上已实现,可能会出现在Less 2.0中,但它需要一些upvotes,请参阅#1857 - 不要犹豫到+1那里。

解决方法

1

您可以通过mixin专精创建“智能参数处理”(请参阅​​Pattern Matching)。 例如。 (少于1.6 +):

.border-radius(@tr: 0, @br: 0, @bl: 0, @tl: 0) when (default()) {
    border-top-right-radius:    @tr;
    border-bottom-right-radius: @br;
    border-bottom-left-radius:  @bl;
    border-top-left-radius:     @tl;
}

.border-radius(@values) when (length(@values) = 4) {
    .border-radius(
        extract(@values, 1),
        extract(@values, 2),
        extract(@values, 3),
        extract(@values, 4));
}

// you also have to provide specializations for
// (length(@values) = 2) and (length(@values) = 3)
// cases if you need to handle them

// ...............................................
// usage:

@myRadius: 3px, 0, 0, 3px;

a {
    .border-radius(1px, 2px);
}

b {
    .border-radius(@myRadius);
}

2

与上面相同,只是一个不那么冗长的变体(少于1.5 +):

.border-radius(@values...) {
    .-() {@tr: 0; @br: 0; @bl: 0; @tl: 0} .-();
    .-() when (length(@values) > 0) {@tr: extract(@values, 1)}
    .-() when (length(@values) > 1) {@br: extract(@values, 2)}
    .-() when (length(@values) > 2) {@bl: extract(@values, 3)}
    .-() when (length(@values) > 3) {@tl: extract(@values, 4)}

    border-top-right-radius:    @tr;
    border-bottom-right-radius: @br;
    border-bottom-left-radius:  @bl;
    border-top-left-radius:     @tl;
}

// ...............................................
// usage:

@myRadius: 3px, 0, 0, 3px;

a {.border-radius(1)}
b {.border-radius(1, 2)}
c {.border-radius(1, 2, 3)}
d {.border-radius(1, 2, 3, 4)}
e {.border-radius(1 2 3 4)}
f {.border-radius(@myRadius)}
// etc.

3

不是一种解决方法,而是“以防万一”的评论,如果用例仅限于基本的CSS属性,那么如果您确实需要默认值为0而不是实际值,则实际上是有问题的CSS“默认值”(即为什么我们需要将.border-radius(1, 2)扩展为border-radius: 1 2 0 0;而不是border-radius: 1 2;?)。相反,我希望混合遵循CSS语法,这样可以简单:

.border-radius(@values...) {
    // ...
    border-radius: @values;
}

// ...............................................
// usage:

@myRadius: 3px 0 0 3px; // no commas here

a {.border-radius(1)}
b {.border-radius(1, 2)}
c {.border-radius(1, 2, 3)}
d {.border-radius(1, 2, 3, 4)}
e {.border-radius(1 2 3 4)}
f {.border-radius(@myRadius)} 

P.S。并且总是如此:如果您对此类内容的用例仅限于供应商前缀,请考虑在构建链中添加自动修复工具,以免浪费时间编写这些供应商的预处理器mixins(see also)。 / p>

答案 1 :(得分:0)

有一种方法可以“在变量中存储多个参数”,但必须设置mixin来处理它,并且必须正确设置变量定义。

使用LESS 1.7.0 +

考虑一下:

@callPropterySet: {@props();};

.border-radius(@topright: 0; @bottomright: 0; @bottomleft: 0; @topleft: 0; @varSet: @callPropterySet) {
    @varSet();
    @props: {
     -webkit-border-top-right-radius: @topright;
  -webkit-border-bottom-right-radius: @bottomright;
   -webkit-border-bottom-left-radius: @bottomleft;
      -webkit-border-top-left-radius: @topleft;

     -moz-border-radius-topright: @topright;
  -moz-border-radius-bottomright: @bottomright;
   -moz-border-radius-bottomleft: @bottomleft;
      -moz-border-radius-topleft: @topleft;

     border-top-right-radius: @topright;
  border-bottom-right-radius: @bottomright;
   border-bottom-left-radius: @bottomleft;
      border-top-left-radius: @topleft;
  };
}

@myRadii: {
    @topright: 3px; 
    @bottomright: 0; 
    @bottomleft: 0; 
    @topleft: 3px;
    @callPropterySet(); //have to include this call again
};

我已将全局变量设置为规则集,以调用mixin中的属性设置@callPropterySet: {@props();};。这允许我将其设置为我重新定义的mixin的默认值,该mixin使用自己的新变量@varSet来调用它。 @props()本身通过@varSet访问的实际规则集是在mixin本身内部定义的。这样就可以灵活地以各种不同的方式调用mix,如下所示:

div {
    .border-radius(@varSet: @myRadii); //call with the single variable
}

.test {
    .border-radius(10px, 5px, 4px, 2px); //call with properties
}

.test2 {
    .border-radius(); //call with defaults
}

所有人都会产生预期的产出。但是,请注意,完成此工作的关键是让该单个变量也将@callPropterySet();作为其规则集的一部分。显然,目前(LESS 1.7)规则集中定义的变量仅在该规则集的范围内被考虑(它们不像mixin那样扩展到范围内)。

所以你现在不能做这样的事情让它发挥作用:

.border-radius(@topright: 0; @bottomright: 0; @bottomleft: 0; @topleft: 0; @varSet...) {
    @varSet();
     -webkit-border-top-right-radius: @topright;
  -webkit-border-bottom-right-radius: @bottomright;
   -webkit-border-bottom-left-radius: @bottomleft;
      -webkit-border-top-left-radius: @topleft;

     -moz-border-radius-topright: @topright;
  -moz-border-radius-bottomright: @bottomright;
   -moz-border-radius-bottomleft: @bottomleft;
      -moz-border-radius-topleft: @topleft;

     border-top-right-radius: @topright;
  border-bottom-right-radius: @bottomright;
   border-bottom-left-radius: @bottomleft;
      border-top-left-radius: @topleft;
}

@myRadii: {
    @topright: 3px; 
    @bottomright: 0; 
    @bottomleft: 0; 
    @topleft: 3px;
};

因为它就像这样:

.border-radius(@topright: 0; @bottomright: 0; @bottomleft: 0; @topleft: 0; @varSet: @callPropterySet) {
    {
      @topright: 3px; 
      @bottomright: 0; 
      @bottomleft: 0; 
      @topleft: 3px;
    }
     -webkit-border-top-right-radius: @topright;
  -webkit-border-bottom-right-radius: @bottomright;
   -webkit-border-bottom-left-radius: @bottomleft;
      -webkit-border-top-left-radius: @topleft;

     -moz-border-radius-topright: @topright;
  -moz-border-radius-bottomright: @bottomright;
   -moz-border-radius-bottomleft: @bottomleft;
      -moz-border-radius-topleft: @topleft;

     border-top-right-radius: @topright;
  border-bottom-right-radius: @bottomright;
   border-bottom-left-radius: @bottomleft;
      border-top-left-radius: @topleft;
}

这将规则集置于与您要设置的属性不同的范围内,因此它们永远不会被设置。