我可以定义一个LESS混入产生一个过渡性质具有可变参数数目?(Can I define a LESS

2019-06-24 03:32发布

我将少一个大型Web应用程序项目,以简化我的CSS。 我有适用过渡到不同数量的属性,例如几个CSS规则:

.movable {
    transition-property: top, left;
    transition-duration: 0.2s;
    transition-timing-function: ease;
}

.fadeAndStretchable {
    transition-property: opacity, width, height, margin;
    transition-duration: 1.5s;
    transition-timing-function: ease-out;
}

(注:我省略了-webkit-moz-o特性在这里为简洁:在现实中每个这些规则是12线长,而不是3)

请注意,这些值transition-property是用逗号分隔。 这是不寻常的CSS:多个值通常是空间分隔(如border: 1px solid #f00 )。 LESS混入可以使用特殊@arguments值产生的所有的混入参数的空间分隔的列表 -但有可能定义一个LESS混入,需要一个可变数量的参数,并把它们转化成以逗号分隔的值列表中,合适的对于transition-property

如果有必要,我很高兴与需要两个混入的解决方案:一个是transition-property ,另一个用于transition-durationtransition-timing-function 。 以下是我试过到目前为止:

试图1:使用与@arguments未命名参数

.transition-property() {
    -webkit-transition-property: @arguments;
    -moz-transition-property: @arguments;
    -o-transition-property: @arguments;
    transition-property: @arguments;
}

.movable {
    .transition-property(top, left);
}

结果:误差小(“无匹配的定义被发现‘.transition属性(上左)’”)

尝试2:使用@arguments与命名参数

.transition-property(@p1, @p2, @p3, @p4, @p5) {
    -webkit-transition-property: @arguments;
    -moz-transition-property: @arguments;
    -o-transition-property: @arguments;
    transition-property: @arguments;
}

.movable {
    .transition-property(top, left);
}

结果:误差小(“无匹配的定义被发现‘.transition属性(上左)’”)

尝试3:使用命名参数与虚拟缺省值

.transition-property(@p1:p1, @p2:p2, @p3:p3, @p4:p4, @p5:p5) {
    -webkit-transition-property: @p1, @p2, @p3, @p4, @p5;
    -moz-transition-property:  @p1, @p2, @p3, @p4, @p5;
    -o-transition-property:  @p1, @p2, @p3, @p4, @p5;
    transition-property:  @p1, @p2, @p3, @p4, @p5;
}

.movable {
    .transition-property(top, left);
}

结果:无误差较小,但它会产生一个CSS规则-webkit-transition-property: top, left, p3, p4, p5 ,浏览器忽略,因为无法识别的属性。

我已经试过各种其他方法(如通过财产作为字符串'top,left' ),但所有的结果在同样的事情:要么不太错误或无效的CSS。

有没有什么办法解决这? 或者,我必须硬着头皮定义超载元数上一组混入的,如

.transition-property(@p1) {...}
.transition-property(@p1, @p2) {...}
.transition-property(@p1, @p2, @p3) {...}
.transition-property(@p1, @p2, @p3, @p4) {...}
etc.

Answer 1:

我已经设法弄清楚感谢卢克页指着我朝...语法。

解决的办法是使用以下命令:

  • ...允许可变参数
  • 反引号的JavaScript的评价
  • 可变字符串插值
  • ~前缀逸出将所得的表达(即,从字符串中的包围它停止LESS)
  • 好老的正则表达式

唷。 下面是导致混入:

.transition-properties(...) {
    -webkit-transition-property: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
}

而这里的完整版了一套完整的浏览器扩展:

.transition-properties(...) {
    @props: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
    -webkit-transition-property: @props;
    -moz-transition-property: @props;
    -o-transition-property: @props;
    transition-property: @props;
}


Answer 2:

也许我误解你的需求。 你为什么不能使用转义字符串?

像这样:

.transition ( @property, @duration, @style: ease-in-out ) {
  -webkit-transition-property: @property;  
  -webkit-transition-duration: @duration;
  -webkit-transition-timing-function: @style;

  -moz-transition-property: @property;  
  -moz-transition-duration: @duration;
  -moz-transition-timing-function: @style;

  -ms-transition-property: @property;  
  -ms-transition-duration: @duration;
  -ms-transition-timing-function: @style;

  -o-transition-property: @property;  
  -o-transition-duration: @duration;
  -o-transition-timing-function: @style;

  transition-property: @property;  
  transition-duration: @duration;
  transition-timing-function: @style;
}

#my-id {
  .transition( ~"background, border-color, color", 2s );
}

这正是我们使用多属性的转变。 从未有过的问题的。



Answer 3:

灵活(LESS 1.5.1+)

该解决方案不使用任何内嵌JavaScript和它允许:

  1. 默认值被设置
  2. 要传递的任何数量的性质,持续时间,延迟等,
  3. 输出无论是在长形式或紧凑的形式
  4. 原料清单输入如果期望的,而不是参数被输入基

如果属性的数目大于持续时间,延迟或定时的数量大,则如果compact输出被设定为持续时间/延迟/定时最终值成为该参数的值对于所有的其他属性以外的数量通过,但如果compact 没有被设置,则该长形式被输出和值每浏览器重复解释的CSS标准离子 。

LESS Mixin

.transition (@props: all; 
             @duration:1s; 
             @delay: 0s; 
             @timing: ease; 
             @compact: true;
             @raw-input: false) {
  .output() when (@raw-input = false) and not (@compact = true) {
  -webkit-transition-property:@props; 
     -moz-transition-property:@props;
      -ms-transition-property:@props;
       -o-transition-property:@props; 
          transition-property:@props;
  -webkit-transition-duration:@duration; 
     -moz-transition-duration:@duration;
      -ms-transition-duration:@duration;
       -o-transition-duration:@duration; 
          transition-duration:@duration;
  -webkit-transition-delay:   @delay; 
     -moz-transition-delay:   @delay;
      -ms-transition-delay:   @delay;
       -o-transition-delay:   @delay; 
          transition-delay:   @delay;
  -webkit-transition-timing-function:@timing; 
     -moz-transition-timing-function:@timing;
      -ms-transition-timing-function:@timing;
       -o-transition-timing-function:@timing; 
          transition-timing-function:@timing;
  }
  .output() when (@raw-input = false) and (@compact = true) {
    @propsLength: length(@props);
    @durationLength: length(@duration);
    @delayLength: length(@delay);
    @timingLength: length(@timing);
    .buildString(@i, @s: ~'') when (@i <= @propsLength) {
      @prop: extract(@props, @i);
      .setDuration() when (@i <= @durationLength) {
        @dur: extract(@duration, @i);
      }
      .setDuration() when (@i > @durationLength) {
        @dur: extract(@duration, @durationLength);
      }
      .setDuration();
      .setDelay() when (@i <= @delayLength) {
        @del: extract(@delay, @i);
      }
      .setDelay() when (@i > @delayLength) {
        @del: extract(@delay, @delayLength);
      }
      .setDelay();
      .setTiming() when (@i <= @timingLength) {
        @time: extract(@timing, @i);
      }
      .setTiming() when (@i > @timingLength) {
        @time: extract(@timing, @timingLength);
      }
      .setTiming();
      .setDivider() when (@i > 1) {
        @divider: ~'@{s},';
      }
      .setDivider() when (@i = 1) {
        @divider: ~'';
      }
      .setDivider();
      @string: @divider @prop @dur @del @time;
      .buildString((@i + 1), @string);  
    }
    .buildString(1);
    .buildString(@i, @s: ~'') when (@i > @propsLength) {
      .compact(@s);
    }
  }
  .output() when not (@raw-input = false) {
    .compact(@raw-input);
  }
  .compact(@string) {
    -webkit-transition:@string; 
       -moz-transition:@string;
        -ms-transition:@string;
         -o-transition:@string; 
            transition:@string;    
  }
  .output();
} 

少用实例

.test {
  .transition();
}
.test-props {
  .transition(width);
}
.test-duration {
  .transition(@duration: 3s);
}
.test-delay {
  .transition(@delay: 10s);
}
.test-timing {
  .transition(@timing: linear);
}
.test-all {
  .transition(height, 4s, 12s, ease-out);
}
.test-multitransitions {
  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
}
.test-not-compact {
  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease; false);
}
.test-raw-input {
  .transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
}

在上述例子中,特别注意到两两件事:(1)多个值需要如何使用逗号列表分开进行传递,但分号分隔的参数组。 所以可视化,它是这样的:

  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
              |---Properties----|-Dur.--|---Delay---|---------Timing--------|
                                |       |           |
                          semicolons divide groups of parameters

(2)如何raw-input例如需要一个结局分号把它考虑逗号作为列表项:

  .transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
                                                               |
                                                    semicolon here needed

实例的CSS输出

.test {
  -webkit-transition:  all 1s 0s ease;
  -moz-transition:  all 1s 0s ease;
  -ms-transition:  all 1s 0s ease;
  -o-transition:  all 1s 0s ease;
  transition:  all 1s 0s ease;
}
.test-props {
  -webkit-transition:  width 1s 0s ease;
  -moz-transition:  width 1s 0s ease;
  -ms-transition:  width 1s 0s ease;
  -o-transition:  width 1s 0s ease;
  transition:  width 1s 0s ease;
}
.test-duration {
  -webkit-transition:  all 3s 0s ease;
  -moz-transition:  all 3s 0s ease;
  -ms-transition:  all 3s 0s ease;
  -o-transition:  all 3s 0s ease;
  transition:  all 3s 0s ease;
}
.test-delay {
  -webkit-transition:  all 1s 10s ease;
  -moz-transition:  all 1s 10s ease;
  -ms-transition:  all 1s 10s ease;
  -o-transition:  all 1s 10s ease;
  transition:  all 1s 10s ease;
}
.test-timing {
  -webkit-transition:  all 1s 0s linear;
  -moz-transition:  all 1s 0s linear;
  -ms-transition:  all 1s 0s linear;
  -o-transition:  all 1s 0s linear;
  transition:  all 1s 0s linear;
}
.test-all {
  -webkit-transition:  height 4s 12s ease-out;
  -moz-transition:  height 4s 12s ease-out;
  -ms-transition:  height 4s 12s ease-out;
  -o-transition:  height 4s 12s ease-out;
  transition:  height 4s 12s ease-out;
}
.test-multitransitions {
  -webkit-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -moz-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -ms-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -o-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
}
.test-not-compact {
  -webkit-transition-property: width, height, top;
  -moz-transition-property: width, height, top;
  -ms-transition-property: width, height, top;
  -o-transition-property: width, height, top;
  transition-property: width, height, top;
  -webkit-transition-duration: 1s, 2s;
  -moz-transition-duration: 1s, 2s;
  -ms-transition-duration: 1s, 2s;
  -o-transition-duration: 1s, 2s;
  transition-duration: 1s, 2s;
  -webkit-transition-delay: 0s, 1s, 3s;
  -moz-transition-delay: 0s, 1s, 3s;
  -ms-transition-delay: 0s, 1s, 3s;
  -o-transition-delay: 0s, 1s, 3s;
  transition-delay: 0s, 1s, 3s;
  -webkit-transition-timing-function: ease-in, ease-out, ease;
  -moz-transition-timing-function: ease-in, ease-out, ease;
  -ms-transition-timing-function: ease-in, ease-out, ease;
  -o-transition-timing-function: ease-in, ease-out, ease;
  transition-timing-function: ease-in, ease-out, ease;
}    
.test-raw-input {
  -webkit-transition: top 1s, bottom 1s, color 3s 1s linear;
  -moz-transition: top 1s, bottom 1s, color 3s 1s linear;
  -ms-transition: top 1s, bottom 1s, color 3s 1s linear;
  -o-transition: top 1s, bottom 1s, color 3s 1s linear;
  transition: top 1s, bottom 1s, color 3s 1s linear;
}

如果长表从不期望的那么混入代码可以减少这样的:

.transition (@props: all; 
             @duration:1s; 
             @delay: 0s; 
             @timing: ease; 
             @raw-input: false) {
  .output() when (@raw-input = false) {
    @propsLength: length(@props);
    @durationLength: length(@duration);
    @delayLength: length(@delay);
    @timingLength: length(@timing);
    .buildString(@i, @s: ~'') when (@i <= @propsLength) {
      @prop: extract(@props, @i);
      .setDuration() when (@i <= @durationLength) {
        @dur: extract(@duration, @i);
      }
      .setDuration() when (@i > @durationLength) {
        @dur: extract(@duration, @durationLength);
      }
      .setDuration();
      .setDelay() when (@i <= @delayLength) {
        @del: extract(@delay, @i);
      }
      .setDelay() when (@i > @delayLength) {
        @del: extract(@delay, @delayLength);
      }
      .setDelay();
      .setTiming() when (@i <= @timingLength) {
        @time: extract(@timing, @i);
      }
      .setTiming() when (@i > @timingLength) {
        @time: extract(@timing, @timingLength);
      }
      .setTiming();
      .setDivider() when (@i > 1) {
        @divider: ~'@{s},';
      }
      .setDivider() when (@i = 1) {
        @divider: ~'';
      }
      .setDivider();
      @string: @divider @prop @dur @del @time;
      .buildString((@i + 1), @string);  
    }
    .buildString(1);
    .buildString(@i, @s: ~'') when (@i > @propsLength) {
      .compact(@s);
    }
  }
  .output() when not (@raw-input = false) {
    .compact(@raw-input);
  }
  .compact(@string) {
    -webkit-transition:@string; 
       -moz-transition:@string;
        -ms-transition:@string;
         -o-transition:@string; 
            transition:@string;    
  }
  .output();
}


Answer 4:

从less.js 1.3以上,你必须指定...参数列表,以表明更多的参数可以添加。 例如

.transition-property(...) {
 foo: @arguments;
}


文章来源: Can I define a LESS mixin to generate a transition-property with a variable number of parameters?