较少的border-radius速记mixin,禁用变量

时间:2013-04-18 10:17:08

标签: variables less mixins css3 shorthand

我正在尝试为border-radius写一个mixin,而不是只有当变量设置的值> = 0时才输出。我将变量中的基值设置为3px,所以如果我输入-1或者例如,border-radius mixin不会在最终样式表中创建任何属性。如果我想为每个角落都有相同的价值,我可以让它工作。但是,如果我想使用速记,即3px 3px 0 0,我无法锻炼如何使其工作。我认为这是一个问题,3px被变量和0在两种情况下都改变了。我的代码目前是

.border-radius(@r) when not (@r = no), (@r = 0) {
    -webkit-border-radius: @r;
       -moz-border-radius: @r;
            border-radius: @r;
}
.border-radius(@r) when (@r = no), (@r = 0) {}

@baseBorderRadius: 3px;
.class1 { .border-radius(@baseBorderRadius); }
// This outputs fine: 3px 3px 3px 3px
.class2 { .border-radius(@baseBorderRadius @baseBorderRadius 0 0); }
// This outputs fine 3px 3px 0 0

@baseBorderRadius: no; // If I change the variable to try and disable/not run the mixin
.class1 { .border-radius(@baseBorderRadius); }
// This does what I want and doesn't run the mixin
.class2 { .border-radius(@baseBorderRadius @baseBorderRadius 0 0); }
// THIS IS THE PROBLEM! This outputs: no no 0 0

所以我需要一种方法来禁用/不运行mixin,如果它包含从全局变量定义的特定值或单词。我这样做是为了一个主题变量文件,根据品牌,公司可能想要圆角或者没有,我宁愿不要在最终样式表中不必要地加载0值。

我真的很感激任何帮助,即使只是为了发现我想要做的事情在LESS中是不可能的。谢谢

2 个答案:

答案 0 :(得分:5)

你可以试试这样的东西,使用多参数混合......并分别用守卫检查每个参数,我分两步编写mixin来分别做守卫

  • 表示带有isnumber()
  • 的值非数字条目(在您的情况下为“no”)
  • 代表值= 0

这里是 LESS 代码(请注意守卫中使用od and):

.border-r-not-0 (@a, @b, @c, @d) when not (@a = 0), not (@b = 0), not (@c = 0), not (@d = 0){
      -webkit-border-radius: @a @b @c @d;
       -moz-border-radius: @a @b @c @d;
            border-radius: @a @b @c @d;
}
.border-radius(@a, @b, @c, @d) when (isnumber(@a)) and (isnumber(@b)) and (isnumber(@c)) and (isnumber(@d)){
    .border-r-not-0(@a, @b, @c, @d);
}

.border-radius(@r) when (isnumber(@r)) and not (@r = 0) {
    -webkit-border-radius: @r;
       -moz-border-radius: @r;
            border-radius: @r;
}

现在

@baseBorderRadius: 3px;
.class1 { .border-radius(@baseBorderRadius); }
.class2 { .border-radius(@baseBorderRadius, @baseBorderRadius, 0, 0); }

CSS 输出为:

.class1 {
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}
.class2 {
  -webkit-border-radius: 3px 3px 0 0;
  -moz-border-radius: 3px 3px 0 0;
  border-radius: 3px 3px 0 0;
}

如果

则没有输出
@baseBorderRadius: no;

因为它没有通过isnumber()测试,

或如果

@baseBorderRadius: 0;

因为所有参数都等于0

注意:为了执行更复杂的操作,例如使用带参数的斜杠/,您必须定义稍微不同的mixin,这需要额外的属性,但我希望您能明白了。

答案 1 :(得分:4)

将“否”视为0

这个经过改进的mixin将“no”视为0,然后查看是否所有内容都设置为0。我不知道这是否正是您所寻求的功能,但这就是我在这里提供的内容(请参阅下面的.class14输出,了解它如何与其他有效值一起使用)。

.border-radius(@r) {
  .check-no(@r) {
    @rad: `'@{r}'.replace(/no/gi, 0).replace(/\b0px|\b0%|\b0em/gi, 0).replace(/[,\[\]]/g, '')`;
  }
  .check-no(@r);

  .set-radius(@rad) when not (@rad = "0") and not (@rad = "0 0") and not (@rad = "0 0 0") and not (@rad = "0 0 0 0") {
    @finalRad: e(@rad);
    -webkit-border-radius: @finalRad;
       -moz-border-radius: @finalRad;
            border-radius: @finalRad;    
  }

  .set-radius(@rad) {}
  .set-radius(@rad);
}

为了完全兼容,必须为所有类型的lengths allowed设置字符串替换/\b0px|\b0%|\b0em/gi(我不会花时间去做)。

所以这个LESS测试代码:

@b1: 3px;
.class1 { .border-radius(@b1); }
.class2 { .border-radius(@b1 @b1 0 0); }
.class3 { .border-radius(0 0); }
.class4 { .border-radius(0px 0); }
.class5 { .border-radius(0% 0); }
.class6 { .border-radius(0em 0); }
.class7 { .border-radius(10px 0); }
.class8 { .border-radius(10% 0); }
.class9 { .border-radius(10em 0); }
.class10 { .border-radius(no); }
.class11 { .border-radius(no no); }
.class12 { .border-radius(no no 0); }
.class13 { .border-radius(no no 0 0); }
.class14 { .border-radius(no no 5px 5px); }

生成此CSS输出(忽略评估为网0的所有实例):

.class1 {
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}
.class2 {
  -webkit-border-radius: 3px 3px 0 0;
  -moz-border-radius: 3px 3px 0 0;
  border-radius: 3px 3px 0 0;
}
.class7 {
  -webkit-border-radius: 10px 0;
  -moz-border-radius: 10px 0;
  border-radius: 10px 0;
}
.class8 {
  -webkit-border-radius: 10% 0;
  -moz-border-radius: 10% 0;
  border-radius: 10% 0;
}
.class9 {
  -webkit-border-radius: 10em 0;
  -moz-border-radius: 10em 0;
  border-radius: 10em 0;
}
.class14 {
  -webkit-border-radius: 0 0 5px 5px;
  -moz-border-radius: 0 0 5px 5px;
  border-radius: 0 0 5px 5px;
}