【问题标题】:Less border-radius shorthand mixin, disable variable更少的边界半径速记混合,禁用变量
【发布时间】:2013-04-11 09:47:58
【问题描述】:

我正在尝试为边界半径编写一个 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 中是不可能的。谢谢

【问题讨论】:

    标签: variables less mixins css shorthand


    【解决方案1】:

    将“否”视为 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;
    }
    

    【讨论】:

    • 我喜欢替换的想法 =) 只是在不同的场景中使用它。
    【解决方案2】:

    您可以尝试这样的方法,使用多参数 mixin ... 并分别检查每个参数的保护,我分两步编写 mixin 以分别执行保护

    • 对于带有isnumber()
    • 的值非数字条目(在您的情况下为“否”)
    • 为价值= 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,它需要额外的属性,但我希望你能得到想法。

    【讨论】:

    • 谢谢@Martin 这工作得很好。我只是无法让我的头脑去锻炼什么时候需要设置!我理解它足以合并前2个mixin,所以非常感谢您的帮助!
    • 这真的很棒,我正在尝试弄清楚如何添加自动和继承的值。我将它应用到 .x-rem mixin 中,它解析属性声明 codepen.io/onebitrocket/details/zFHcC 的 rem 和 px 后备
    猜你喜欢
    • 2012-04-23
    • 1970-01-01
    • 2014-04-30
    • 2012-01-21
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多